web-dev-qa-db-ja.com

string、intなどからの列挙型

拡張メソッドを使用して、列挙型の拡張メソッドToInt()ToString()などを作成することにより、列挙型を文字列、intなどの他のデータ型に変換するメソッドを作成できます。

私は他の方法でどのように実装するのでしょうか。 FromInt(int)FromString(string)など。私が知る限り、MyEnum.FromInt()(静的)拡張メソッドは作成できません。それで、これに対する可能なアプローチは何ですか?

26
Louis Rhys

Enumの拡張メソッドでintまたはstringを汚染することは避け、代わりに古き良き静的ヘルパークラスを使用することもできます。

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

これらの拡張メソッドが本当に必要ですか?

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

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

逆の方法はおそらく...逆の方法です;)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>();

残念ながらEnumには一般的な制約がないため、実行時にTEnumタイプをチェックする必要があります。簡単にするために、その検証はEnum.ToObjectおよびEnum.Parseメソッドに任せます。

7

なぜ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
RedDeckWins

別のアプローチ(質問の文字列部分):

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

3
Benjol

できるよ:

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

Intとstringに拡張メソッドを作成できます。

または、他の静的クラスで静的メソッドを作成します。 EnumHelper.FromInt(int)のようなものかもしれません。

しかし、私は一つの質問を投げかけます:なぜあなたは文字列または整数に変換したいのですか?おそらくシリアライゼーションを除いて、通常は列挙可能オブジェクトを処理する方法ではありません。ただし、これは独自のコードではなく、何らかのインフラストラクチャで処理する必要があります。

0
Euphoric