2

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?

Gadzooks34
  • 1,718
  • 2
  • 20
  • 29

8 Answers8

2

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;
}
abatishchev
  • 98,240
  • 88
  • 296
  • 433
  • Wrt to the System.DayOfWeek, the month and day values I'm using are just examples. In the real app they're not related at all to days or times. For the code you've shown, the DoSomething() function will only be able to operate on the Days enum. If I try to supply a different enum it will fail. – Gadzooks34 Sep 14 '12 at 16:46
  • @Gadzooks34: I got your point. But unfortunately C# doesn't support yet generic constraint by enum. See my updated post for description. – abatishchev Sep 14 '12 at 19:35
0

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.

Nikhil Agrawal
  • 47,018
  • 22
  • 121
  • 208
  • 1
    That looks great but it doesn't work. The compiler will complain that doSomething() has an invalid argument, even when the enum is derived from int. – Gadzooks34 Sep 14 '12 at 16:44
  • Well, that's back to what I put in my example. Yes, casting to an int in the function will work, it's just clumsier than I would like. – Gadzooks34 Sep 14 '12 at 16:53
0

Any problem with System.DateTime?

This would be the most pragmatic type to use.

oleksii
  • 35,458
  • 16
  • 93
  • 163
0

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}
Sconibulus
  • 732
  • 9
  • 21
  • I tried that but I don't think you can actually define the function like that. Defining doSomething(enum x) expects that the entire enumeration is being passed, not just one of its values, which isn't what I want (sorry if that was unclear from my pseudocode). – Gadzooks34 Sep 14 '12 at 16:52
  • sorry, what I was trying to suggest was that you have an overload for each enum, e.g. `dosomething(days x)` `dosomething(months x)` the problem is that that could get big if you have a lot of different enums. – Sconibulus Sep 14 '12 at 17:07
  • Yeah. The problem is that the function is defined in a base library, and users will then be defining their own enums without access to the source code for the function. – Gadzooks34 Sep 14 '12 at 17:12
  • You might be able to adapt what you need from this answer, although I'm not certain the performance will be great. http://stackoverflow.com/a/7628058/1623719 – Sconibulus Sep 14 '12 at 18:26
0

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

Community
  • 1
  • 1
Eyal H
  • 991
  • 5
  • 22
  • That's a very cool trick. I think that will work. The only thing I'm worried about is performance (though I failed to mention that in my question). Seems like the conversion might be slow: [Faster version of Convert.ChangeType](http://stackoverflow.com/questions/1532197/faster-version-of-convert-changetype) – Gadzooks34 Sep 14 '12 at 17:06
  • well if runtime performance is more important I would suggest something on the line of generics, expensive somewhere else but better on the performance. – Eyal H Sep 14 '12 at 17:46
0

DId you try to overload a function by parameter:

int DoSomething(Enum1 value)
int DoSomething(Enum2 value)
Fabio
  • 31,528
  • 4
  • 33
  • 72
0
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

Praveen
  • 100
  • 8
  • I believe if you copy and paste your code into the ide you will find that it does not work, and instead yields the problem I am describing (function doSomething() argument is of invalid type). – Gadzooks34 Sep 14 '12 at 17:23
  • why it will not work.. Its a working code you why would it return an invalid argument type.. you just need to look in to it. int c = ee.doSomething((int)testenums.months.march),check your enum type is it short or int – Praveen Sep 14 '12 at 17:36
0

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;
                    }
Fabio
  • 31,528
  • 4
  • 33
  • 72