Создать общий метод, ограничивающий перечисление

6 ответов

С тех пор Enum реализации Типа IConvertible интерфейс, лучшая реализация должна быть чем-то вроде этого:

public T GetEnumFromString<T>(string value) where T : struct, IConvertible
{
   if (!typeof(T).IsEnum) 
   {
      throw new ArgumentException("T must be an enumerated type");
   }

   //...
}

Это все еще разрешит передавать типов значения, реализовывая IConvertible. Возможности редки все же.

938
ответ дан shA.t 9 May 2018 в 08:26
поделиться

Я изменил образец dimarzionist. Эта версия будет только работать с Перечислениями и не позволять структурам пройти.

public static T ParseEnum<T>(string enumString)
    where T : struct // enum 
    {
    if (String.IsNullOrEmpty(enumString) || !typeof(T).IsEnum)
       throw new Exception("Type given must be an Enum");
    try
    {

       return (T)Enum.Parse(typeof(T), enumString, true);
    }
    catch (Exception ex)
    {
       return default(T);
    }
}
11
ответ дан Bivoauc 9 May 2018 в 08:26
поделиться

Надежда это полезно:

public static TValue ParseEnum<TValue>(string value, TValue defaultValue)
                  where TValue : struct // enum 
{
      try
      {
            if (String.IsNullOrEmpty(value))
                  return defaultValue;
            return (TValue)Enum.Parse(typeof (TValue), value);
      }
      catch(Exception ex)
      {
            return defaultValue;
      }
}
4
ответ дан nawfal 9 May 2018 в 08:26
поделиться

Можно определить статического конструктора для класса, который проверит, что тип T является перечислением, и выдайте исключение, если это не. Это - метод, упомянутый Jeffery Richter в его книжном CLR через C#.

internal sealed class GenericTypeThatRequiresAnEnum<T> {
    static GenericTypeThatRequiresAnEnum() {
        if (!typeof(T).IsEnum) {
        throw new ArgumentException("T must be an enumerated type");
        }
    }
}

Тогда в методе синтаксического анализа, можно просто использовать Перечисление. Синтаксический анализ (typeof (T), вход, верный) для преобразования от строки до перечисления. Последний истинный параметр для того, чтобы игнорировать регистр входа.

18
ответ дан Karg 9 May 2018 в 08:26
поделиться

Interestingly enough, apparently this is possible in other langauges (Managed C++, IL directly).

To Quote:

... Both constraints actually produce valid IL and can also be consumed by C# if written in another language (you can declare those constraints in managed C++ or in IL).

Who knows

3
ответ дан 19 December 2019 в 20:15
поделиться

У меня есть особое требование, когда я требовал использовать перечисление с текстом, связанным со значением перечисления. Например, когда я использую enum для указания типа ошибки, требуется описать детали ошибки.

public static class XmlEnumExtension
{
    public static string ReadXmlEnumAttribute(this Enum value)
    {
        if (value == null) throw new ArgumentNullException("value");
        var attribs = (XmlEnumAttribute[]) value.GetType().GetField(value.ToString()).GetCustomAttributes(typeof (XmlEnumAttribute), true);
        return attribs.Length > 0 ? attribs[0].Name : value.ToString();
    }

    public static T ParseXmlEnumAttribute<T>(this string str)
    {
        foreach (T item in Enum.GetValues(typeof(T)))
        {
            var attribs = (XmlEnumAttribute[])item.GetType().GetField(item.ToString()).GetCustomAttributes(typeof(XmlEnumAttribute), true);
            if(attribs.Length > 0 && attribs[0].Name.Equals(str)) return item;
        }
        return (T)Enum.Parse(typeof(T), str, true);
    }
}

public enum MyEnum
{
    [XmlEnum("First Value")]
    One,
    [XmlEnum("Second Value")]
    Two,
    Three
}

 static void Main()
 {
    // Parsing from XmlEnum attribute
    var str = "Second Value";
    var me = str.ParseXmlEnumAttribute<MyEnum>();
    System.Console.WriteLine(me.ReadXmlEnumAttribute());
    // Parsing without XmlEnum
    str = "Three";
    me = str.ParseXmlEnumAttribute<MyEnum>();
    System.Console.WriteLine(me.ReadXmlEnumAttribute());
    me = MyEnum.One;
    System.Console.WriteLine(me.ReadXmlEnumAttribute());
}
5
ответ дан 19 December 2019 в 20:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: