代码之家  ›  专栏  ›  技术社区  ›  Adriaan Stander

C中枚举分析的通用版本#

  •  39
  • Adriaan Stander  · 技术社区  · 15 年前

    我经常想知道为什么C还没有实现一个通用的枚举。

    让我说我有

    enum MyEnum
    {
       Value1,
       Value2
    }
    

    从一个xml文件/db条目,我希望创建一个枚举。

    MyEnum val = (MyEnum)Enum.Parse(typeof(MyEnum), "value1", true);
    

    它不能像这样实现吗?

    MyEnum cal = Enum.Parse<MyEnum>("value1");
    

    这似乎是一个小问题,但似乎是一个被忽视的问题。

    有什么想法吗?

    6 回复  |  直到 9 年前
        1
  •  34
  •   Community CDub    8 年前

    它已经在.NET 4中实现;)请看一下 here .

    MyEnum cal;
    if (!Enum.TryParse<MyEnum>("value1", out cal))
       throw new Exception("value1 is not valid member of enumeration MyEnum");
    

    还有讨论 here 包含一些有趣的要点。

        2
  •  16
  •   Ian Boyd    12 年前

    以所需的问题语法:

    MyEnum cal = Toolkit.Parse<MyEnum>("value1");
    

    注释 :因为C禁止您添加静态扩展,所以您必须将函数存放在其他地方。我用的是静态的 Toolkit 包含所有这些有用位的类:

    /// <summary>
    /// Converts the string representation of the name or numeric value of one or
    //  more enumerated constants to an equivalent enumerated object.
    /// </summary>
    /// <typeparam name="TEnum">An enumeration type.</typeparam>
    /// <param name="value">A string containing the name or value to convert.</param>
    /// <returns>An object of type TEnum whose value is represented by value</returns>
    /// <exception cref="System.ArgumentNullException">enumType or value is null.</exception>
    /// <exception cref=" System.ArgumentException"> enumType is not an System.Enum. -or- 
    /// value is either an empty string or only contains white space.-or- 
    /// value is a name, but not one of the named constants defined for the enumeration.</exception>
    /// <exception cref="System.OverflowException">value is outside the range of the underlying type of enumType.</exception>
    public static TEnum Parse<TEnum>(String value) where TEnum : struct
    {
       return (TEnum)Enum.Parse(typeof(TEnum), value);
    }
    
        3
  •  6
  •   kvb    15 年前

    尽管限制于 System.Enum C_不允许,在.NET和C_can中允许 使用 具有此类约束的类型或方法。见Jon Skeet Unconstrained Melody 库,其中包括完全按照您的需要执行的代码。

        4
  •  2
  •   user2397863    10 年前
    public class EnumHelper
    {
        public static T? TryParse<T>(string text)
            where T: struct
        {
            if (string.IsNullOrEmpty(text))
            {
                return null;
            }
    
            T r;
    
            if (Enum.TryParse<T>(text, out r))
            {
                return r;
            }
    
            return null;
        }
    }
    
        5
  •  1
  •   Jimmy    9 年前

    稍微修改了@ian boyd's answer版本,使用扩展方法避免在调用中指定静态类名:

    MyEnum cal = "value1".Parse<MyEnum>();
    
    /// <summary>
    /// Converts the string representation of the name or numeric value of one or
    //  more enumerated constants to an equivalent enumerated object.
    /// </summary>
    /// <typeparam name="TEnum">An enumeration type.</typeparam>
    /// <returns>An object of type TEnum whose value is represented by value</returns>
    /// <exception cref="System.ArgumentNullException">enumType or value is null.</exception>
    /// <exception cref=" System.ArgumentException"> enumType is not an System.Enum. -or- 
    /// value is either an empty string or only contains white space.-or- 
    /// value is a name, but not one of the named constants defined for the enumeration.</exception>
    /// <exception cref="System.OverflowException">value is outside the range of the underlying type of enumType.</exception>
    public static TEnum Parse<TEnum>(this String value) where TEnum : struct
    {
       return (TEnum)Enum.Parse(typeof(TEnum), value);
    }
    
        6
  •  0
  •   Jose Tepedino    11 年前

    在用一些方法稍作调整的同时,尝试构建类似于初始方案的内容:

    MyEnum cal = Enum.Parse<MyEnum>("value1");
    

    在我看来,这种语法在C中是不可能的,因为枚举类型被视为不可为空。

    如果我们调用“enum.typarse”方法,传递一个与枚举项不对应的值, 枚举的默认值将在“out”变量中返回。所以我们需要测试 首先是“enum.typarse”结果,因为

    MyEnum cal;
    Enum.TryParse<MyEnum>("value1", out cal);
    

    检查“cal”值并不总是能给出可靠的结果。