Rami Rami - 1 month ago 16
C# Question

How to use generic Tryparse with Enum?

I'm trying to build generic function that get from user string and try to parse it to Enum valuse like this:

private Enum getEnumStringEnumType(Type i_EnumType)
{
string userInputString = string.Empty;
Enum resultInputType;
bool enumParseResult = false;

while (!enumParseResult)
{
userInputString = System.Console.ReadLine();
enumParseResult = Enum.TryParse(userInputString, true, out resultInputType);
}
}


But i get:

The type 'System.Enum' must be a non-nullable value type in order to use it as parameter 'TEnum' in the generic type or method 'System.Enum.TryParse<TEnum>(string, bool, out TEnum) .


The Error means that i need to decalare a specific Enum for resultInputType?
How can I fix this ?
Thanks.

Answer

The TryParse method has the following signature:

TryParse<TEnum>(string value, bool ignoreCase, out TEnum result)
    where TEnum : struct

It has a generic type parameter TEnum that must be a struct and that it uses to determine the type of enum that it is parsing. When you don't provide it explicitly (as you did), it will take the type of the resultInputType variable, which is Enum (and not the type of the enumeration itself).

Note that Enum is a class (despite it inheriting from ValueType) and therefore it does not satisfy the requirement that TEnum is a struct.

You can solve this by giving the method a generic argument instead of a Type parameter. The generic type parameter TEnum must have the same constraints (i.e. struct) as the type parameter on the TryParse function.

So try this:

private static TEnum GetEnumStringEnumType<TEnum>()
    where TEnum : struct
{
    string userInputString = string.Empty;
    TEnum resultInputType = default(TEnum);
    bool enumParseResult = false;

    while (!enumParseResult)
    {                
        userInputString = System.Console.ReadLine();
        enumParseResult = Enum.TryParse(userInputString, true, out resultInputType);
    }
    return resultInputType;
}

To call the method, use:

GetEnumStringEnumType<MyEnum>();