2011-01-18 7 views
25

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

他の方法を実装する方法が不思議です。 FromInt(int)FromString(string)など私が知る限り、​​(静的)拡張メソッドを作成することはできません。だからこそ可能なアプローチは何ですか?

+6

拡張メソッドを作成する'int'と' string'では、 'enum'ではなく... – Oded

+1

は、 'int'や' string'のような汚染はありません。なぜなら、それらは多く使われていて、ほとんど私の列挙型に関係していないからです。 –

+0

そのようなメソッド(私のToEnum <>のような)は、(ToString()のような)ほとんどの場合、ほぼ一般的な目的になります。 –

答えて

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

'FromInt'はコンパイルされません。 'int'型を 'T'_に変換できません。 – Cel

+0

'T'は列挙型ですか?それはint enumですか? – Jamiec

+1

私はそれを呼び出すことさえできず、コンパイルに失敗しました - これは代わりに動作するようになっています: 'public static T ToEnum (this int value) { return(T)Enum.Parse(typeof(T)、value.ToString() )); } – Cel

0

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

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

しかし、私は1つの質問を提出します。なぜ文字列またはintに変換したいのですか?それは、直列化を除いて、列挙型でどのように正常に動作するかではありません。しかし、それはあなた自身のコードではなく、ある種のインフラストラクチャによって処理されるべきです。

+0

あなたの質問:複数のライブラリの周りにラッパーを作成しています。彼らはいくつかの文字列に関して同じ規則を持っていないので、同じ規則を持つように列挙型を作成しようとします。 –

4

なぜ、FromIntをキャストするのとは異なり、extenstionメソッドが必要ですか?あなたが本当にこれらの拡張メソッドが必要です

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 
} 
+0

stringvalueとintvalueが基になる値と同じでない場合はどうなりますか? –

+0

私はあなたが言っていることをかなり得ていません。あなたは文字列内で何が起こるかを尋ねていますかintは列挙値を表していませんか? – RedDeckWins

+0

はい。つまり、パースまたはキャストを使用することはできません –

19

を使用することができますか?

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

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

周りの他の方法は...多分周りの他の方法だろう;)型のパラメータとして列挙型を取るジェネリック拡張メソッドで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の方法にしておきます。

+0

私はこれが異なる過負荷の1つの方法であることが好きです。 –

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