5

One piece of code is worth a thousand words...

public enum enTest { a, b, c }

public void PrintEnum<T>()
{
    foreach (var E in Enum.GetValues(typeof(T)))
    Debug.WriteLine(E.ToString());
}

PrintEnum<enTest>();
PrintEnum<enTest?>();    // This will cause failure in Enum.GetValues()

The above is simplified from a larger problem to illustrate the failure.

Does anyone know how can I iterate through (or get all the values inside) when someone passing me a Nullable Enum?

Thanks in advance.

s k
  • 4,342
  • 3
  • 42
  • 61
  • 1
    Does [Nullable.GetUnderLyingType](https://msdn.microsoft.com/en-us/library/system.nullable.getunderlyingtype%28v=vs.110%29.aspx) help? – germi Jun 26 '15 at 10:20
  • 1
    "One piece of code is worth a thousand words..." - but showing the error would help a lot too... along with using conventional names in your sample. – Jon Skeet Jun 26 '15 at 10:21
  • http://stackoverflow.com/a/5181559/1466456 – Jaanus Varus Jun 26 '15 at 10:22
  • 2
    There is a bit of a misconception that you have "a nullable int" or "a nullable enum". You don't really, what you have is a type that can hold an int, or hold an enum, and also have the concept of null, but this type is neither an int nor an enum, it's a nullable value holding an int or an enum. There is compiler magic in the compilers to handle this and lift/promote the nullable types value out of the nullable value in expressions. So basically, nobody is passing you a nullable enum, they're passing you a `Nullable` which is not an enum, but T is an enum. As such, you need to get the T. – Lasse V. Karlsen Jun 26 '15 at 10:23
  • You should really constrain the type `T` as much as possible to prevent passing in anything that's not an `enum`. (e.g. `where T : struct, IConvertible`) – DavidG Jun 26 '15 at 10:25
  • 3
    As @germi mentioned, using nullable.GetUnderlyingType would give you back the required type, and since it gives back null if not a nullable, you could simply coalesce to keep it safe for normal usage: `Enum.GetValues(Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T)))` – Me.Name Jun 26 '15 at 10:27
  • @Me.Name Didn't know about `Nullable.GetUnderlyingType`, nice! Thanks! – Lasse V. Karlsen Jun 26 '15 at 10:27
  • 3
    A side-question would be if the method is passed a `Nullable` holding an enum, should the method also print "null" as a legal value? – Lasse V. Karlsen Jun 26 '15 at 10:28
  • @DavidF - it doesn't look like you can, a, constrain a type to an enum, b, constrain a type to a type or it's nullable version. – Daniel James Bryars Jun 26 '15 at 10:35
  • 1
    @DanielJamesBryars Assuming you meant me and not a fictional DavidF? I know you can't constrain to an `enum` which is why I suggested `struct, IConvertible`. – DavidG Jun 26 '15 at 10:38
  • @DavidG - yes I did :). Oh I see yes, I hadn't appreciated that. – Daniel James Bryars Jun 26 '15 at 10:56
  • @Lasse - yes, in fact my task is to create a selection list when passed in an enum by the caller. So if they are passing me a nullable enum, I will have to create a list with -none- as an option. It was not shown in the question for simplicity – s k Jun 27 '15 at 00:38

1 Answers1

9

How about this?

public static void PrintEnum<T>()
        {
            Type t = typeof (T);
            if (t.IsGenericType)
            {
                //Assume it's a nullable enum
                t = typeof (T).GenericTypeArguments[0];
            }

            foreach (var E in Enum.GetValues(t))
                Console.WriteLine(E.ToString());
        }
Daniel James Bryars
  • 4,429
  • 3
  • 39
  • 57