【问题标题】:Enum from string, int, etc来自字符串、整数等的枚举
【发布时间】:2011-06-10 22:57:39
【问题描述】:

使用扩展方法,我们可以通过为枚举创建扩展方法ToInt()ToString() 等来创建将枚举转换为字符串、int 等其他数据类型的方法。

我想知道如何以相反的方式实现,例如FromInt(int)FromString(string) 等。据我所知,我无法创建 MyEnum.FromInt()(静态)扩展方法。那么有哪些可能的方法呢?

【问题讨论】:

  • 您在intstring 上创建扩展方法,而不是enum...
  • 不会污染intstring,因为它们被大量使用并且大多与我的枚举无关?
  • 这样的方法(就像我下面的 ToEnum)就足够通用了(几乎就像 ToString())。

标签: c# .net enums extension-methods type-conversion


【解决方案1】:

我会避免使用枚举的扩展方法污染 int 或字符串,而是可能需要一个好的老式静态帮助器类。

public static class EnumHelper
{
   public static T FromInt<T>(int value)
   {
       return (T)value;
   }

  public static T FromString<T>(string value)
  {
     return (T) Enum.Parse(typeof(T),value);
  }
}

【讨论】:

  • FromInt 无法为我编译,无法将类型 'int' 转换为 'T' ?
  • T 是枚举吗?它是一个 int 枚举吗?
  • 我什至没有调用它并且编译失败 - 我让它工作了:public static T ToEnum&lt;T&gt;(this int value) { return (T)Enum.Parse(typeof(T), value.ToString()); }
  • 出现异常的机会很大,我会将此解决方案与 Reddeckwins 下面的解决方案结合使用(使用 IsDefined 和 TryParse)来避免不必要的问题,当然要视情况而定。
【解决方案2】:

你真的需要那些扩展方法吗?

MyEnum fromInt = (MyEnum)someIntValue;
MyEnum fromString = (MyEnum)Enum.Parse(typeof(MyEnum), someStringValue, true);

int intFromEnum = (int)MyEnum.SomeValue;
string stringFromEnum = MyEnum.SomeValue.ToString();

【讨论】:

    【解决方案3】:

    另一种方法可能是……另一种方法;)使用 通用扩展方法 扩展 int 和字符串,这将把枚举的类型作为类型参数:

    public static TEnum ToEnum<TEnum>(this int val)
    {
        return (TEnum) System.Enum.ToObject(typeof(TEnum), val);
    }
    

    public static TEnum ToEnum<TEnum>(this string val)
    {
        return (TEnum) System.Enum.Parse(typeof(TEnum), val);
    }
    

    用法:

    var redFromInt = 141.ToEnum<System.Drawing.KnownColor>();
    var redFromString = "Red".ToEnum<System.Drawing.KnownColor>();
    

    不幸的是 Enums 没有通用约束,所以我们必须在运行时检查 TEnum 类型;为简化起见,我们将验证留给Enum.ToObjectEnum.Parse 方法。

    【讨论】:

    • 我喜欢这是一种具有不同重载的方法。
    【解决方案4】:

    为什么你想要 FromInt 一个扩展方法而不是强制转换它?

    MyEnum fromInt;
    if(Enum.IsDefined(typeof(MyEnum), intvalue))
    {
        fromInt = (MyEnum) intvalue;
    }
    else
    {
        //not valid
    }
    

    或者,对于字符串,您可以使用Enum.TryParse

    MyEnum fromString;
    if (Enum.TryParse<MyEnum>(stringvalue, out fromString))
    {
        //succeeded
    }
    else
    {
        //not valid
    }
    

    【讨论】:

    • 如果 stringvalue 和 intvalue 与底层值不同怎么办?
    • 我不太明白你在说什么。您是在问 string 或 int 中发生的事情不代表任何枚举值吗?
    【解决方案5】:

    另一种方法(针对您问题的字符串部分):

    /// <summary>
    /// Static class for generic parsing of string to enum
    /// </summary>
    /// <typeparam name="T">Type of the enum to be parsed to</typeparam>
    public static class Enum<T>
    {
        /// <summary>
        /// Parses the specified value from string to the given Enum type.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        public static T Parse(string value)
        {
            //Null check
            if(value == null) throw new ArgumentNullException("value");
            //Empty string check
            value = value.Trim();
            if(value.Length == 0) throw new ArgumentException("Must specify valid information for parsing in the string", "value");
            //Not enum check
            Type t = typeof(T);
            if(!t.IsEnum) throw new ArgumentException("Type provided must be an Enum", "T");
    
            return (T)Enum.Parse(typeof(T), value);
        }
    }
    

    (部分灵感来自:http://devlicious.com/blogs/christopher_bennage/archive/2007/09/13/my-new-little-friend-enum-lt-t-gt.aspx

    【讨论】:

      【解决方案6】:

      你可以这样做:

      public static class EnumExtensions
      {
          public static Enum FromInt32(this Enum obj, Int32 value)
          {
              return (Enum)((Object)(value));
          }
      
          public static Enum FromString(this Enum obj, String value)
          {
              return (Enum)Enum.Parse(obj.GetType(), value);
          }
      }
      

      或者:

      public static class Int32Extensions
      {
          public static Enum ToEnum(this Int32 obj)
          {
              return (Enum)((Object)(obj));
          }
      }
      
      public static class StringExtensions
      {
          public static Enum ToEnum(this Enum obj, String value)
          {
              return (Enum)Enum.Parse(obj.GetType(), value);
          }
      }
      

      【讨论】:

        【解决方案7】:

        您可以在 int 和 string 上创建扩展方法。

        或者在其他一些静态类上创建静态方法。也许像 EnumHelper.FromInt(int) 之类的东西。

        但我会提出一个问题:为什么要转换为字符串或整数?除了序列化之外,这不是您通常使用可枚举的方式。但这应该由某种基础设施来处理,而不是您自己的代码。

        【讨论】:

        • 是您的问题:我正在围绕多个库创建一个包装器。它们对于某些字符串没有相同的约定,所以我尝试创建一个枚举,以便它们具有相同的约定。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-23
        • 1970-01-01
        • 1970-01-01
        • 2019-07-04
        相关资源
        最近更新 更多