来自string,int等的枚举

时间:2011-01-18 08:41:32

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

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

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

7 个答案:

答案 0 :(得分:32)

我会避免使用枚举的扩展方法来污染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);
  }
}

答案 1 :(得分:21)

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

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

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

答案 2 :(得分:7)

另一种方式可能是......反过来;)使用泛型扩展方法扩展int和string,它将枚举的类型作为类型参数:

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方法。

答案 3 :(得分: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
}

答案 4 :(得分:3)

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

/// <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

答案 5 :(得分:2)

你可以这样做:

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);
    }
}

答案 6 :(得分:0)

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

或者在其他静态类上创建静态方法。也许像EnumHelper.FromInt(int)。

但我会提出一个问题:为什么要转换为字符串或int?它不是你如何使用枚举,除了序列化。但这应该由某种基础设施来处理,而不是你自己的代码。