拡張メソッドを使用して、列挙型の拡張メソッドToInt()
、ToString()
などを作成することにより、列挙型を文字列、intなどの他のデータ型に変換するメソッドを作成できます。
私は他の方法でどのように実装するのでしょうか。 FromInt(int)
、FromString(string)
など。私が知る限り、MyEnum.FromInt()
(静的)拡張メソッドは作成できません。それで、これに対する可能なアプローチは何ですか?
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);
}
}
これらの拡張メソッドが本当に必要ですか?
MyEnum fromInt = (MyEnum)someIntValue;
MyEnum fromString = (MyEnum)Enum.Parse(typeof(MyEnum), someStringValue, true);
int intFromEnum = (int)MyEnum.SomeValue;
string stringFromEnum = MyEnum.SomeValue.ToString();
逆の方法はおそらく...逆の方法です;)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
メソッドに任せます。
なぜ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
}
別のアプローチ(質問の文字列部分):
/// <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 )
できるよ:
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);
}
}
Intとstringに拡張メソッドを作成できます。
または、他の静的クラスで静的メソッドを作成します。 EnumHelper.FromInt(int)のようなものかもしれません。
しかし、私は一つの質問を投げかけます:なぜあなたは文字列または整数に変換したいのですか?おそらくシリアライゼーションを除いて、通常は列挙可能オブジェクトを処理する方法ではありません。ただし、これは独自のコードではなく、何らかのインフラストラクチャで処理する必要があります。