Общий анализатор строковых значений Enum в С#?

У меня странный вопрос о разборе перечислений из строк. Как бы то ни было, моему приложению необходимо обрабатывать несколько перечислений из файла конфигурации. Однако я не хочу писать процедуры синтаксического анализа для каждого типа перечисления (поскольку их много).

Проблема, с которой я столкнулся, заключается в том, что следующий код показывает какую-то странную ошибку: тип T должен быть типом значения, не допускающим значение NULL, или чем-то в этом роде. Я думал, что перечисления по умолчанию не обнуляемые?

Если я ограничу тип T с помощью where T : enum, все остальное внутри тела метода (кроме оператора if Enum.TryParse) будет подчеркнуто как ошибка.

Может ли кто-нибудь помочь с этой странной мизерной проблемой?

Спасибо, Мартин

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;
}

Пользователь запросил опубликовать текст ошибки (это во время кода, а не во время компиляции/выполнения), так что вот оно:

Тип «T» должен быть типом значения, не допускающим значение NULL, чтобы использовать его в качестве параметра TEnum в универсальном типе или методе «System.Enum.TryParse(string, out TEnum)».


person bleepzter    schedule 14.06.2011    source источник
comment
Можете прикрепить ошибку? без условия where ваш код должен работать.   -  person Nathan Tregillus    schedule 14.06.2011
comment
@ jdv-Ян де Ваан, так это работает? Я имею в виду, что я знаю, что перечисления действительно являются целыми, а целые имеют тип структуры System.Int32... но действительно ли это работает?   -  person bleepzter    schedule 14.06.2011
comment
Взгляните на stackoverflow.com/questions/3811042/, это может помочь.   -  person Nair    schedule 14.06.2011
comment
@bleep: перечисление может происходить от любого целочисленного типа (byte, long и т. д.).   -  person Gabe    schedule 14.06.2011
comment
@bleepzter: Теперь, когда вы добавили сообщение об ошибке, я вижу подтверждение того, что это решение. Так что, оглядываясь назад, я должен был опубликовать это как ответ.   -  person    schedule 14.06.2011


Ответы (2)


Хорошо, имея в виду эту информацию, я понимаю, на что жалуется метод Enum.TryParse.

поместите общее ограничение на метод следующим образом:

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

Или просто поместите то же ограничение, что и в методе Enum.TryParse.

where T : struct, new()

вы можете найти это определение здесь:

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

person Nathan Tregillus    schedule 14.06.2011
comment
Обратите внимание, что where T : ValueType не работает, ValueType можно обнулить, это должно быть where T : struct. - person Greg Bair; 10.09.2014

Поскольку C# не позволит вам сделать where T : enum, вам придется использовать where T : struct.

Обратите внимание, что есть способы обойти это ограничение, как Michael предложенный.

person Gabe    schedule 14.06.2011