Добавление ограничений для Nullable Enum - PullRequest
5 голосов
/ 28 сентября 2010

Я пишу некоторые функции Enum, и у меня есть следующее:

public static T ConvertStringToEnumValue<T>(string valueToConvert, bool isCaseSensitive)
{
    if (typeof(T).BaseType.FullName != "System.Enum" && typeof(T).BaseType.FullName != "System.ValueType")
    {
       throw new ArgumentException("Type must be of Enum and not " + typeof (T).BaseType.FullName);
    }

    if (String.IsNullOrWhiteSpace(valueToConvert))
      return (T)typeof(T).TypeInitializer.Invoke(null);

    valueToConvert = valueToConvert.Replace(" ", "");              

    if (typeof(T).BaseType.FullName == "System.ValueType")
    {
        return (T)Enum.Parse(Nullable.GetUnderlyingType(typeof(T)), valueToConvert, !isCaseSensitive);
    }

    return (T)Enum.Parse(typeof(T), valueToConvert, !isCaseSensitive);
}

Я называю это так:

EnumHelper.ConvertStringToEnumValue<Enums.Animals?>("Cat");

Теперь я хочу добавить ограничения к T в Enum, например (что я получил из статьи Stackoverflow ): where T : struct, IConvertible, но у меня возникли проблемы, поскольку T должен иметь возможность принимать обнуляемые перечисления , Сообщение об ошибке гласит:

Тип 'Enums.Animals?' должен быть необнуляемым типом значения, чтобы использовать его в качестве параметра 'T' в универсальном типе или методе

Есть ли способ сделать это, или мне просто нужно полагаться на проверку во время выполнения, которую я имею внутри метода?

Спасибо всем!

Ответы [ 2 ]

9 голосов
/ 28 сентября 2010

Нет, нет ограничения, которое говорит: «T должен быть типом значения, включая типы значений, допускающие значение NULL».

Однако, один из вариантов - разделить метод на:

public static T ConvertStringToEnumValue<T>(...) where T : struct
public static T? ConvertStringToNullableEnumValue<T>(...) where T : struct

Кроме всего прочего, реализация каждого метода была бы также более простой.

Конечно, мы не знаем, как вы собираетесь использовать этот код - но если вы собираетесь вызыватьэто напрямую из неуниверсальных методов, это был бы мой предложенный подход.

Конечно, это все равно не помешает кому-то назвать его с T=int или чем-то подобнымВозможно, вы захотите взглянуть на Неограниченная мелодия для более жестких ограничений.

1 голос
/ 28 сентября 2010

Существует хитрость, включающая C ++ / CLI, которая допускает общие ограничения для Enums. Написать базовый абстрактный класс в C ++ / CLI с ограничением Enum. Ссылка на библиотеку в проекте C # и реализация базового класса.

...