3

I am using C# to write a class that takes an enum type parameter, like this:

class EnumWrapper<T>
    where T: Enum
{
}

Inside the class, I have a method that takes an argument of type T, and I need to cast it to an int, like this:

void DoSomething(T arg)
{
    int a = (int)arg;
}

But the compiler issues a CS0030 error "Cannot convert type 'T' to 'int'. Something similar happens when I try to cast an int back into a T. However, this works with a fixed enum type that is not provided via a type parameter. For example, this works fine:

void DoSomething(DayOfWeek arg)
{
    int a = (int)arg;
}

Why is this happening, and how can I cast between a generic enum type and int?

CesarGon
  • 15,099
  • 6
  • 57
  • 85
  • 4
    Remember that enums can have any integer base type -- you can have `enum Foo : ulong` if you so wish. What do you want your code to do in that case? – canton7 Apr 08 '21 at 10:46
  • @canton7: Yes, I am aware of this. :-) – CesarGon Apr 08 '21 at 10:55
  • That's the "why is this happening" part. For the "How can I cast..." part, answer my question: What do you want your code to do in that case? – canton7 Apr 08 '21 at 10:55
  • I'm wondering why you need such a wrapper class. It sounds like you are possibly doing something 'unusual', hence your problem, when there may be a better way to solve your actual problem without a wrapper – Neil Apr 08 '21 at 12:04
  • @Neil, I am developing a wrapper because I need two features: a string description of each enum value, and hierarchically organised values. – CesarGon Apr 08 '21 at 14:11
  • 1
    @CesarGon Please check out the end of my answer :) I also had a very similar problem a couple of years ago – Hasan Emrah Süngü Apr 08 '21 at 14:14
  • @HasanEmrahSüngü: Yes, thank you! – CesarGon Apr 08 '21 at 14:42
  • 1
    String descriptions should probably use the `[Description]` attribute (which already supports resx/translations etc). Hierarchy, could also come from a custom attribute, I guess `[Hierarchy("parent")]` ? – Neil Apr 08 '21 at 16:02
  • Thanks for the ideas, @Neil. We are currently exploring alternative approaches, and attributes are one of them. – CesarGon Apr 08 '21 at 16:12

1 Answers1

4

You may add IConvertible to generic constraint and use ToInt32 method, something like

class EnumWrapper<T>
    where T : Enum, IConvertible
{
    void DoSomething(T arg)
    {
        int a = arg.ToInt32(null);
    }
}

Have a look at the Enum constraint for details. Also, as mentioned in comments, it isn't necessary that your enum is based on int type

Pavel Anikhouski
  • 21,776
  • 12
  • 51
  • 66
  • 2
    Alternatively, skip the constraint and call `Convert.ToInt32(arg)` (which internally tests for `IConvertible`). – canton7 Apr 08 '21 at 10:51
  • Lacks the "back" part of the title. But that is already explained here: https://stackoverflow.com/a/10387134/284240 – Tim Schmelter Apr 08 '21 at 11:06