Say I have a function that takes an integer as an argument. I'd like to be able to use an enumerated list as a way to keep the integer values organized.
For example, I'd ideally like to be able to define these (pseudocode):
public enum days
{
monday,
tuesday,
etc...
}
public enum months
{
january,
february,
etc...
}
int doSomething(enum x)
{
return x + 1;
}
and then be able to call the function using either of the enumerated lists like this:
int a = doSomething(days.monday);
int y = doSomething(months.february);
This obviously won't work as-is because doSomething needs to be defined using just one of the enumerations (i.e. either days or months). I know of a couple of options. One is to simply cast to an int:
int a = doSomething((int)days.monday);
int y = doSomething((int)months.february);
The only problem with this is that this function gets called MANY places in my code, and it's clumsy to have to keep putting "(int)"s all over the place (one of the main motivations for grouping these int values together into enums in the first place is to make the code more readable).
Another option is to avoid enums altogether, and instead bundle the values into a container class, something like:
static class Days
{
static int x = 0;
static int monday = x++;
static int tuesday = x++;
}
Again, this will work but just seems awfully cumbersome when I have a lot of these container classes to define.
The answer might very well be that there is no simpler way, and that I need to be a grown-up and just accept one of these options. But I thought I would get a sanity check on that before committing to it. Is there a third option?
What is your issue?
public enum Days : short
{
Monday = 1,
Tuesday = 2,
...
}
DoSomething(Days.Monday);
void DoSomething(Days day)
{
Days nextDay = day + 1;
}
Also note already built-in enum System.DayOfWeek.
I got OP's point but afaik this is not supported by C# yet:
void DoSomething<T>(T e) where T : enum
{
T next = e + 1;
}
Any problem with System.DateTime?
This would be the most pragmatic type to use.
You could overload your method, if you really just want the int value, perhaps something like this?
int dosomething(enum x)
{return dosomething((int)x)}
int dosomething(int x)
{return x+1}
yes you can do so
public enum days : int
{
monday,
tuesday,
...
}
automatically monday becomes 0 and tuesday becomes 1 and so on
public enum months : int
{
january,
february,
...
}
same for months
int doSomething(Enum x)
{
return (int)x + 1;
}
and call it as
int a = doSomething(days.monday);
or call it as
int a = doSomething(months.january);
now days.monday equals 0 and after method a becomes 1.
Or if you don't want to change all existing Enums:
public static int DoSomething(Enum x)
{
int xInt = (int)Convert.ChangeType(x, x.GetTypeCode());
DoSomething(xInt);
}
as stated here: enums-returning-int-value
public enum days : int
{ monday, tuesday,
}
public enum months :int
{ january, february, march,
}
public int doSomething(int z)
{
return z + 1;
}
// your calling method int c = ee.doSomething((int)testenums.months.march); int c = ee.doSomething((int)testenums.day.February);
working code as you always pass enum and which is of type int you just need to parse and send this code perfectly works.. let me know
DId you try to overload a function by parameter:
int DoSomething(Enum1 value)
int DoSomething(Enum2 value)
I spent a “little” time on this, because got a same problem(solution).
So here is my solution which work fine on (.NET 4), Windows Forms:
VB:NET
Private Function DoSomething(Of TEnum As {IComparable, IConvertible, IFormattable})(ByVal valueEnum As TEnum) As Int32
Dim i As Int32 = CInt(Convert.ChangeType(valueEnum, valueEnum.GetTypeCode()))
//Do something with int
i += 1
Return i
End Function
C#
private int DoSomething<TEnum>(TEnum valueEnum) where TEnum: IComparable, IConvertible, IFormattable
{
int i = 0;
i = (int)Convert.ChangeType(valueEnum, valueEnum.GetTypeCode());
i++;
return i;
}
Related
I need to get the current weekday number of the current week.
If I use DateTime.Now.DayOfWeek I get Monday, but it would be much easier to work with if I get 1 for Monday, 7 for Sunday etc. Thanks beforehand!
You can use this:
day1 = (int)DateTime.Now.DayOfWeek;
You can create an extension method to hide the implementation details.
Using an extension method and constraining T to IConvertible does the trick, but as of C# 7.3 Enum is an available constraint type:
public static class EnumExtensions
{
public static int ToInt<T>(this T source) where T : Enum
{
return (int) (IConvertible) source;
}
}
This then allows you to write:
DateTime.Now.DayOfWeek.ToInt();
Example:
Console.WriteLine(DayOfWeek.Monday.ToInt()); // outputs 1
Note: this solution assumes that int is used as the underlying Enum type.
DateTime.Now.DayOfWeek is an enum, and it is of (int) type, so the easiest way would be #faheem999 's answer.
But, if you are dealing with Enums with unknown type's, such as (byte , sbyte , short , ushort , int , uint , long or ulong), then either you need to know Enum type, or use another method:
DayOfWeek dayOfWeek = DateTime.Now.DayOfWeek;
object val = Convert.ChangeType(dayOfWeek, dayOfWeek.GetTypeCode());
For more information, look at this question Get int value from enum in C#
I need to get the numeric position of an enum in its definition.
Consider the following enum - it is used for bit fields but the status names
would be useful if they had the values on the right that I have commented.
[Flags]
public enum StatusFlags
{
None = 0, // 0 -- these commented indexes are the numbers I also would like
Untested = 1, // 1 to associate with the enum names.
Passed_Programming = 2, // 2
Failed_Programming = 4, // 3
// ... many more
}
I have created a static method as follows, which works for what I want.
public static int GetStatusID(this StatusFlags flag)
{
int i = 0;
foreach (StatusFlags val in Enum.GetValues(typeof(StatusFlags)))
{
if (flag == val) break;
i++;
}
return i;
}
It is used like this:
StatusFlags f = StatusFlags.Failed_Programming;
// I want the position i.e value of 3 not the value the enum is associated with i.e 4
int Index = f.GetStatusID();
Is there is a better way to do this?
How about using attributes on your enum? Something like this:
[Flags]
public enum StatusFlags
{
[Index=0]
None = 0,
[Index=1]
Untested = 1,
[Index=2]
Passed_Programming = 2,
[Index=3]
Failed_Programming = 4,
// ... many more
}
Then you can the index value of your enum like this:
var type = typeof(StatusFlags);
var statusFlag = type.GetMember(StatusFlags.Untested.ToString());
var attributes = statusFlag [0].GetCustomAttributes(typeof(IndexAttribute),false);
var index = int.Parse(((IndexAttribute)attributes[0]).Index); //if you need an int value
A deleted answer here suggested something that resembled
public static int GetStatusID(this StatusFlags flag)
{
return Array.IndexOf(Enum.GetValues(typeof(StatusFlags)), flag);
}
and was just missing the syntactical point that IndexOf is a static function in the Array class, not an extension method. I like it though for brevity.
You could do this:
public static int GetStatusID(this StatusFlags flag)
{
return
Enum
.GetValues(typeof(StatusFlags))
.Cast<StatusFlags>()
.Select((f, n) => new { f, n })
.Where(fn => fn.f == flag)
.Select(fn => fn.n)
.DefaultIfEmpty(0)
.First();
}
How about just using math? He says the flags go up in powers of 2
int GetStatusID(this StatusFlags flag)
{
if (((int)flag) == 0) return 0;
return (Math.Log((double)flag) / Math.Log(2D)) + 1;
}
If each flag has only 1 bit set like that then the index is just Math.Log2((int)flag) + 1. However Math.Log2 is a floating-point operation and is very slow so don't use it
If you're using .NET Core then there are BitOperations.Log2 and BitOperations.TrailingZeroCount which map directly to hardware instructions like TZCNT/BSF in x86 or CLZ in ARM, hence are much more efficient and the result is like this
public static int GetStatusID(this StatusFlags flag)
{
if ((int)flag == 0)
return 0;
return BitOperations.Log2((int)flag);
// or return BitOperations.TrailingZeroCount((int)flag) + 1;
}
If you're using an older .NET framework then calculate see the way to calculate integer log2 quickly in these questions
What's the quickest way to compute log2 of an integer in C#?
Fastest implementation of log2(int) and log2(float)
Fast way of finding most and least significant bit set in a 64-bit integer
In C#, when defining a public method like:
public int myMethod(String someString)
{
//code
}
What does the int indicate apart from the type integer? What confuses me is that the method is using a String as arguments in this case.
It is the return type of the method. In this case a 32-bit signed integer with a range of
-2,147,483,648 .. +2,147,483,647
It corresponds to the .NET type System.Int32. int is just a handy C# alias for it.
You would return a value like this
public int Square(int i)
{
return i * i;
}
And you could call it like this
int sqr = Square(7); // Returns 49
// Or
double d = Math.Sin(Square(3));
If you do not need the return value, you can safely ignore it.
int i;
Int32.TryParse("123", out i); // We ignore the `bool` return value here.
If you have no return value you would use the keyword void in place of the type. void is not a real type.
public void PrintSquare(int i)
{
Console.WriteLine(i * i);
}
And you would call it like this
PrintSquare(7);
The method in your example accepts a string as input parameter and returns an int as result. A practical example would be a method that counts the number of vowels in a string.
public int NumberOfVowels(string s)
{
const string vowels = "aeiouAEIOU";
int n = 0;
for (int i = 0; i < s.Length; i++) {
if (vowels.Contains(s[i])) {
n++;
}
}
return n;
}
It stands for "integer", and it means the method returns an integer number of 32 bits, also known in C# as Int32.
As previously stated, it's what the method returns.
For example:
public string x()
{
return 5;
}
Would error. 5 is definitely not a string!
public int x()
{
return 5;
}
Would be correct; since 5 can be considered an int (Short for integer, which is, basically, just a number which cannot have a decimal point. There's also float, double, long and decimal, which are worth reading about)
There must be no way of it not returning, for example, if you do:
public int x()
{
if (false)
{
return 5;
}
}
It will error because if the expression is false (It is of course) it won't be returning an int, it won't return anything.
If you use the keyword void, it means it does not return anything. Ex:
public void x()
{
someFunction("xyz");
}
It's fine that it doesn't return as it's a void method.
I don't think you're new to programming judging by your reputation, but just in case, when you return something you pass it back from the method, for example:
int x;
public int seven()
{
return 7;
}
x = seven();
x will become the return value of the function seven.
Note that the 'dynamic' type works here:
public dynamic x(int x, int y)
{
if (x == y)
{
return "hello";
}
return 5
}
But if you're new to C# don't get caught up in dynamic typing just yet. :)
It is the type of the return value.
Everyone is correct here but the definition from msdn:
"Int32 is an immutable value type that represents signed integers with values that range from negative 2,147,483,648 (which is represented by the Int32.MinValue constant) through positive 2,147,483,647 (which is represented by the Int32.MaxValue constant. The .NET Framework also includes an unsigned 32-bit integer value type, UInt32, which represents values that range from 0 to 4,294,967,295."
Found here on MSDN: Int32 Structure
I suggest you read the documentation found in the link above. It is extremely useful.
Let me start off by stating that I know the assignment operator in C# cannot be overloaded/overridden. However, if I have a class like so:
public class Time
{
private int Hour, Minute;
public int minutes;
public Time(int m)
{
this.minutes = m;
this.Hour = m / 60;
this.Minute = m % 60;
}
public Time(int hh, int mm)
{
this.minutes = 60 * hh + mm;
this.Hour = hh;
this.Minute = mm;
}
public static explicit operator Time(int i1)
{
return new Time(i1);
}
}
Two things:
1) Is the explicit conversion overload at the bottom necessary?
2) I want to do
Time newTime = 510;
and have Hour and Minute reflect the new minutes. Without making another object, is the only way to make a function like so:
public void changeminutes(int m)
{
this.minutes = m;
this.Hour = m / 60;
this.Minute = m % 60;
}
and do this:
Time newTime = new Time();
newTime.changeminutes(510);
edit:
I probably should have mentioned that I'm still in learning C#. A lot of your suggestions are flying over my head. Sorry.
next edit :
This isn't necessarily about time. I just used it to illustrate my example.
You can create an implicit cast from int to Time.
However, I recommend against it.
Unless they're between equivalent types (eg, int and long), implicit casts will end up creating lots of confusion.
In addition, it isn't obvious that that should mean minutes and not seconds.
You can create a much nicer syntax using extension methods:
Time t = 510.Minutes();
It looks like you're trying to make a reference type behave like a value type, which is... um, tricky. If you really don't want to use the constructor for this (and explaining why that is might help us answer), you can use a static "factory" method:
public static Time FromMinutes(int m)
{
return new Time(m);
}
And use it like this:
var t = Time.FromMinutes(510);
This is similar to what the TimeSpan class lets you do.
For you case an implicit conversion would work but...
Conversions are not to be used when you loose data, or even semantics like in this case. You know that the number will become a Time, but you don't know which unit of time will the number be converted into.
If somebody is going to read the code it will not have any clue what the number represents without looking at the internal definition of the Time class. Think if that was in an outside project. Debugging hell? :)
First, you want to use implicit casting to achieve Time x = 123;, but as others are pointing out it's probably a poor design choice because it's not immediately clear what the number represents (and most people would assume a Unix timestamp).
Second, why not use the Minutes property to set minutes, and simply convert the value into the proper value, while changing Hours?
time.Minutes = 510;
// in class def:
public int Minutes
{
get { return minutes; }
set
{
hours = value / 60;
minutes = value % 60;
}
}
This is a very basic question, and if what I am thinking of doing is complicated/involved, then I don't expect you to go into detail... I've read that this may involve structs or hash or some other scary procedure I've not gotten to yet. If so, I'm sure it'll get me soon.
Working on learning classes, methods, and return values.
I'd like to have my class/method return Current Hour and Minute. Simple enough, really.
Is this constructed correctly, or properly?
class MyClass
{
public int GetHour (int hr, int min)
{
DateTime dt = DateTime.Now;
int hour = dt.Hour;
int minute = dt.Minute;
return hour;
return minute;
}
}
And, calling it from Main(): Getting some errors (No overload for method and Unreachable code detected)
static void Main ( string[] args )
{
MyClass mc = new MyClass ();
Console.WriteLine ("Hour: {0} \n Minute: {1}", mc.GetHour());
Console.ReadLine ();
}
Question is: Am I Close?
As mentioned by #ChaosPandion, in that specific case you would return a DateTime struct.
In general, however, you would have the following options:
Using out parameters
This is a simple way that will usually always work. However, it is a bit clunky, as the result is returned where you usually would expect the function arguments to be passed and the method signature might get lengthy and hard to refactor.
public void GetTime(out int hr, out int min)
{
DateTime dt = DateTime.Now;
hr = dt.Hour;
min = dt.Minute;
}
static void Main(string[] args)
{
// declare variables for out parameters first
int hour, minute;
GetTime(out hour, out minute);
}
Using an array
This is a simple method that works well if the values to be returned have the same type.
public int[] GetTime()
{
DateTime dt = DateTime.Now;
return new[] { dt.Hour, dt.Minute};
}
Using a property bag (A property bag is a simple class which only has properties)
This is very convenient and allows easy modification of the type and number of returned values later on without changing the method signature.
class A
{
int Prop1 { get; set; }
int Prop2 { get; set; }
}
public A SomeMethod()
{
return new A() { Prop1 = 1, Prop2 = 2 }
}
Using a Tuple
In C# 4.0 (requires VS 2010) you can use the Tuple<T1, T2, ...> class:
public Tuple<int, int> GetTime()
{
DateTime dt = DateTime.Now;
return Tuple.Create(dt.Hour, dt.Minute);
}
C# 7.0 Tuples
C# 7.0 adds support for multiple return values. You can write code like this to return an implicitly created tuple:
(string, string, string) LookupName(long id) // tuple return type
{
... // retrieve first, middle and last from data storage
return (first, middle, last); // tuple literal
}
The tuple elements are names Item1, Item2, etc by default, but you can also specify names, e.g.
(string first, string middle, string last) LookupName(long id) // tuple return type
{
... // retrieve first, middle and last from data storage
return (first, middle, last); // tuple literal
}
and then access the tuple elements via those names:
var names = LookupName(id);
WriteLine($"found {names.first} {names.last}.");
C# does not support multiple return values so in this case you should return a DateTime struct which is the idiomatic approach. The client code can simply ignore the properties that they don't care about. You could create your own simple struct but it really isn't worth the effort.
C# doesn't support the idea of directly returning multiple values from a method in that fashion. However there are a couple of ways to create methods which return multiple values. The first is to use ref / out parameters.
public void GetHourMinute(out int hour, out int minute) {
var now = DateTime.Now;
hour = now.Hour;
minute = now.Minute;
}
The second is to create a wrapper type which encapsulates the two values. Starting in 4.0 this can be made a bit easier by using the Tuple type.
public Tuple<int,int> GetHourMinute() {
var now = DateTime.Now;
return Tuple.Create(now.Hour, now.Minute);
}
I suggest you return the DateTime object. Then in your main method you call Hour and Minute properties.
1: You can't have two returns. Once the compiler reaches the return statement, the operation of the method is finished.
2: Why would you want your method to receive parameters if you don't use them? DateTime.Now gives you the current time, if you'll think of yourself as that method - what do you need in order to complete your task? Nothing.
So, practical tips:
1. Actually, the DateTime does what you need better than your method.
Console.WriteLine ("Hour: {0} \n Minute: {1}", DateTime.Now.Hour,DateTime.Now.Minute);
Would have been better,
but let's ignore that and consider it an exercise in classes.
2 Returning two values is against the concept of a method - a method returns one thing (there are exceptions as out ref, but we'll ignore them).
You can actually see that in your own code - your method name is GetHour not GetHourAndMinutes. I don't think I've ever seen a method's name with the word "and" - a method does only one thing.
Yeah, you can only return one 'thing' from method in C#.
The other problem you have is you are calling a method without any parameters. The things in the brackets:
public int GetHour (int hr, int min) // here
{
}
Are parameters. And you need to specify them when calling the method, like so:
mc.GetHour(1, 2);
But of course, in your case, it doesn't make sense to do this.
To answer the general question of: "How do I return more than one thing?" You encapsulate it in a class, set the properties, and return that class. It so happens, in the example you've given, the DateTime class does just that.
Hope this is helpful.
You cant return multiple value. TimeSpan is exactly what you are looking for. Create an object of that with hour, minute and even second that you want to capture and return it.
Come to think about it, for what you need above, you dont even have to write the method above. Just use DateTime.Now.TimeOfDay directly in your code
Sorry, you can't do that. You'd be better served returning an array or an object. You could return the DateTime object and use it.
Also as stated, your function signature wasn't being called properly.
class MyClass
{
public int[] GetHour ()
{
DateTime dt = DateTime.Now;
int hour = dt.Hour;
int minute = dt.Minute;
return new int[]{hour, minute};
}
}
static void Main ( string[] args )
{
MyClass mc = new MyClass ();
int[] temp = mc.GetHour();
Console.WriteLine ("Hour: {0} \n Minute: {1}", temp[0], temp[1]);
Console.ReadLine ();
}
In C# a method can return multiple times, if you use yield return format.
using System.Collections.Generic;
namespace YieldReturn
{
class Program
{
public static void Main(string[] args)
{
MyClass mc = new MyClass();
IEnumerator<int> enu = mc.GetHour().GetEnumerator();
enu.MoveNext();
int hour = enu.Current;
enu.MoveNext();
int min = enu.Current;
Console.WriteLine("Hour {0} min {1}", hour, min);
Console.ReadKey(true);
}
}
class MyClass
{
DateTime dt;
public MyClass()
{
dt = DateTime.Now;
}
public IEnumerable<int> GetHour()
{
int hour = dt.Hour;
int minute = dt.Minute;
yield return hour;
yield return minute;
}
}
}
Gives "Hour 8 min 50"
You can't return twice, only once.
Several return values at once require lambda expressions, and AFAIK, only Python is capable of that.
Syntax there goes like this:
return x, y
So maybe you should try IronPython, and then decompile to C#.
In C#, there are exactly two ways to return more than one value:
1. Use arguments as call by reference, that way you can assign 3 variables and then return.
2. Use some kind of struct/class/array/tuple/vector and place your multiple values into it.
Call by reference is something like this:
public static void xxx(ref var1, ref
var2, ref var3) {
var1 = 123;
var2 = 456;
var3 = 789;
return; }
then you do:
int a =1;
int b=2;
int c=3;
xxx(ref a, ref b, ref c);
Console.WriteLine(a.ToString());
Console.WriteLine(b.ToString());
Console.WriteLine(c.ToString());
The question I would like to ask you is why do you want to return multiple values? Returning multiple values for me means having multiple responsibilities in the function and that should be a big don't since it is violating SRP. But, if those return values are related maybe they make an object that you're missing and should be created instead? Or a list with one type of object.
So for short. Why? Encapsulate your return values in ONE object? Don't do multiple things in one function.
EDIT: In your case I wouldn't even wrap your functionality in a function just write:
static void Main ( string[] args )
{
MyClass mc = new MyClass ();
DateTime now = DateTime.Now;
int hour = now.Hour;
int min = now.Minute;
Console.WriteLine ("Hour: {0} \n Minute: {1}", hour, min);
Console.ReadLine ();
}
And your function name GetHour doesn't do what the function says... if it says GetHour it should return the hour and not the hour plus the minute.