来自字符串、整数等的枚举
Posted
技术标签:
【中文标题】来自字符串、整数等的枚举【英文标题】:Enum from string, int, etc 【发布时间】:2011-06-10 22:57:39 【问题描述】:使用扩展方法,我们可以通过为枚举创建扩展方法ToInt()
、ToString()
等来创建将枚举转换为字符串、int 等其他数据类型的方法。
我想知道如何以相反的方式实现,例如FromInt(int)
、FromString(string)
等。据我所知,我无法创建 MyEnum.FromInt()
(静态)扩展方法。那么有哪些可能的方法呢?
【问题讨论】:
您在int
和string
上创建扩展方法,而不是enum
...
不会污染int
和string
,因为它们被大量使用并且大多与我的枚举无关?
这样的方法(就像我下面的 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<T>(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.ToObject
和Enum.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:如何将整数转换为等效的枚举字符串? [复制]