来自字符串、整数等的枚举

Posted

技术标签:

【中文标题】来自字符串、整数等的枚举【英文标题】: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())。 【参考方案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) 之类的东西。

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

【讨论】:

是您的问题:我正在围绕多个库创建一个包装器。它们对于某些字符串没有相同的约定,所以我尝试创建一个枚举,以便它们具有相同的约定。

以上是关于来自字符串、整数等的枚举的主要内容,如果未能解决你的问题,请参考以下文章

Django/Python:如何将整数转换为等效的枚举字符串? [复制]

Django/Python:如何将整数转换为等效的枚举字符串? [复制]

c++ 转换运算符重载、枚举、整数和字符

在 HTML/PHP 下拉列表中列出枚举字符串,其中包含来自 2 个 MSSQL 表的值

c 枚举 获得枚举项的字符串

如果它们来自数据源,如何在 graphql 模式中表示枚举?