3

I have a weird question about parsing enumerations from strings. As it is, my app needs to handle parsing of few enumerations from a config file. However, I don't want to write parsing routines for each enumeration type (as there are many).

The problem I am facing is that the following code is showing some weird error - The type of T has to be a non-nullable value type or something of the sort. I thought that enums are by default non-nullable?

If I restrict the type of T using where T : enum, everything else inside the method body (other than the if Enum.TryParse statement) is underlined as error.

Can anyone help with this weird minuscule issue?

Thanks, Martin

public static T GetConfigEnumValue<T>(NameValueCollection config,
                                      string configKey, 
                                      T defaultValue) // where T : enum ?
{
    if (config == null)
    {
        return defaultValue;
    }

    if (config[configKey] == null)
    {
        return defaultValue;
    }

    T result = defaultValue;
    string configValue = config[configKey].Trim();

    if (string.IsNullOrEmpty(configValue))
    {
        return defaultValue;
    }

    //Gives me an Error - T has to be a non nullable value type?
    if( ! Enum.TryParse<T>(configValue, out result) )
    {
        result = defaultValue;
    }

    //Gives me the same error:
    //if( ! Enum.TryParse<typeof(T)>(configValue, out result) )  ...

    return result;
}

A user requested to post the text of the error (it is at code time, not compile/runtime), so here it goes:

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

Gustavo Mori
  • 8,319
  • 3
  • 38
  • 52
bleepzter
  • 9,607
  • 11
  • 41
  • 64
  • Can you attach the error? without the where condition, it looks like your code should work. – Nathan Tregillus Jun 14 '11 at 17:17
  • @jdv-Jan de Vaan so does this work? I mean i know enum's are really ints and ints are of type System.Int32 struct... but does it really work? – bleepzter Jun 14 '11 at 17:28
  • Have a look at http://stackoverflow.com/questions/3811042/adding-constraints-for-nullable-enum, it might help. – Nair Jun 14 '11 at 17:30
  • 1
    @bleep: An enum can derive from any integral type (`byte`, `long`, etc.). – Gabe Jun 14 '11 at 17:33
  • @bleepzter: Now that you added the error message, I see confirmed that this is the solution. So in retrospect I should have posted it as an answer. –  Jun 14 '11 at 18:28

3 Answers3

1

Ah ok, with that information in mind, I see what the Enum.TryParse method is complaining about.

put a generic constraint on the method like so:

public static T GetConfigEnumValue<T>(NameValueCollection config, 
                                      string configKey, 
                                      T defaultValue) // where T : ValueType

Or just place the same constraint that is on the Enum.TryParse method.

where T : struct, new()

you can find this definition here:

http://msdn.microsoft.com/en-us/library/dd783499.aspx

Gustavo Mori
  • 8,319
  • 3
  • 38
  • 52
Nathan Tregillus
  • 6,006
  • 3
  • 52
  • 91
  • Note that `where T : ValueType` doesn't work, `ValueType` is nullable, it has to be a `where T : struct`. – Greg Bair Sep 10 '14 at 18:29
1
public static T GetConfigEnumValue<T>(NameValueCollection config, string configKey, T defaultValue)
{
    if (config == null)
    {
        return defaultValue;
    }

    if (config[configKey] == null)
    {
        return defaultValue;
    }

    T result = defaultValue;
    string configValue = config[configKey].Trim();

    if (string.IsNullOrEmpty(configValue))
    {
        return defaultValue;
    }

    try
    {
        result = (T)Enum.Parse(typeof(T), configValue, true);
    }
    catch
    {
        result = defaultValue;
    }

    return result;
}
bleepzter
  • 9,607
  • 11
  • 41
  • 64
0

Since C# won't let you do where T : enum, you have to use where T : struct.

Note that there are ways around that restriction as Michael suggested.

Community
  • 1
  • 1
Gabe
  • 84,912
  • 12
  • 139
  • 238