-3

If I have a parameter of type System.Enum, how can I get the int representation of the contained value? I know if I had the actual Enum-derived class instance, I could just cast it to an int, but that doesn't seem to work on a System.Enum.

More succinctly, what is the correct body of this GetEnumValue function?

public enum Order
{
    First,
    Second,
    Third
}

//Returns int representation of the passed enum.
//(e.g. should return 1 if passed Order.First, 2 if Order.Second, etc.)
//Should work on any other enum as well.
public int GetEnumValue(Enum enumInstance)
{
    ???
}

(I'm ignoring the issue that an arbitrary enum might not have int as its underlying type to simplify the problem. I'll need to allow for that as well, but the main wall I'm running into is simply not being able to get the value from an Enum param.)

ANSWER- Thanks to Chetan's comment, a solution is "return Convert.ToInt32(enumInstance);"

NOTE- This is not a duplicate of Get int value from enum in C# as some have commented. The important difference is I am asking about if the variable is of type System.Enum not a derived Enum. The simple int cast method in that answer does not work here.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Curtis
  • 85
  • 5
  • How will you call this method? – Chetan Mar 15 '23 at 01:58
  • Did you try doing `return Convert.ToInt32(enumInstance);` ? – Chetan Mar 15 '23 at 02:02
  • Your code example does not compile - your enum class does not have a class name. It feels like you are overthinking this - enums can easily be cast to their underlying values: [get-int-value-from-enum-in-c-sharp](https://stackoverflow.com/questions/943398/get-int-value-from-enum-in-c-sharp) But it is a little unclear - can you give a clear example of what doesn't work? – topsail Mar 15 '23 at 02:22
  • Chetan- I'd call it with something like "int enumValue = GetEnumValue(Order.First);" More importantly, your "Convert.ToInt32(enumInstance)" suggestion seems to work. That's what I needed, thanks! – Curtis Mar 15 '23 at 02:41
  • topsail- Sorry, forgot the name for the enum. Edited that in. I know concrete enums can simply be cast to their integer type as in the answer you linked, but variables of the the abstract base type System.Enum class cannot. – Curtis Mar 15 '23 at 02:42
  • @topsail the code definitely compiles. It isn't necessary to pass a named enum instance. passing `System.Enum` is a valid scenario. – David L Mar 15 '23 at 02:48
  • Rufus- the dupe you (or someone else) marked this as is not a dupe and simply casting to an int does not work in this case. Please see my question edit and the answer posted by David L. I did research and tried searching in several ways with no luck. Thanks for the reply though. :) – Curtis Mar 15 '23 at 07:27
  • Your question specifically is answered by [this answer](https://stackoverflow.com/a/20310398/466862) on the duplicate. – Mark Rotteveel Mar 28 '23 at 08:24

1 Answers1

0

You can use the method suggested in the linked answer in the comments, which uses the Convert class:

public int GetEnumValue(Enum enumInstance)
{
    return (int)Convert.ChangeType(enumInstance, typeof(int));
}

However, this requires boxing/unboxing which may not be optimal for your scenario.

In hot paths, you can use Unsafe.As<TFrom, TTo from System.Runtime.CompilerServices and avoid the boxing entirely by taking advantage of generics:

public int GetEnumValueOptimized<T>(T enumInstance) where T : Enum
{
    return Unsafe.As<T, int>(ref enumInstance);
}

If you cannot guarantee that the enum is always backed by int, you can add a defensive check or you can expand the method to handle more backing types:

public int GetEnumValueOptimized<T>(T enumInstance) where T : Enum
{
    if (Unsafe.SizeOf<T>() != Unsafe.SizeOf<int>())
    {
        return -1;
    }

    return Unsafe.As<T, int>(ref enumInstance);
}
David L
  • 32,885
  • 8
  • 62
  • 93