vs2008 では、任意の列挙に適用される拡張メソッドを作成することは可能ですか。
特定の列挙に対して拡張メソッドを記述できることは知っていますが、単一の拡張メソッドを使用してすべての列挙を実行できるようにしたいと考えています。これは可能ですか?
vs2008 では、任意の列挙に適用される拡張メソッドを作成することは可能ですか。
特定の列挙に対して拡張メソッドを記述できることは知っていますが、単一の拡張メソッドを使用してすべての列挙を実行できるようにしたいと考えています。これは可能ですか?
はい、基本Enum
型に対してコーディングするだけです。
public static void Something(this Enum e)
{
// code here
}
欠点は、enum の基本型が何であるかに応じて、を使用して実際の基本型を見つけたり、キャストしたり、さまざまなブランチを下ったりするなど、かなり厄介なことをEnum.GetUnderlyingType
することになる可能性がありますが、いくつかの良い用途を見つけることができますそれ(たとえば、すべての列挙型に適用されるIsOneOf
andメソッドがあります)。IsCombinationOf
PS:メソッドを作成するときは、あまりお勧めできませんが、enum の基本型としてfloat
andを使用できるので、それらと符号なし値にはいくつかの特別なケースが必要になることを覚えておいてください。double
はい、できます。ターゲット拡張タイプは typeEnum
です。C# では、これは次のように行われます。
public static void EnumExtension(this Enum e)
{
}
またはVBで次のように:
<Extension()> _
Public Sub EnumExtension(ByVal s As Enum)
End Sub
参考までに、これは私が使用できた Enum Extension メソッドの素晴らしい例です。列挙型に対して大文字と小文字を区別しない TryParse() 関数を実装します。
public static class ExtensionMethods
{
public static bool TryParse<T>(this Enum theEnum, string strType,
out T result)
{
string strTypeFixed = strType.Replace(' ', '_');
if (Enum.IsDefined(typeof(T), strTypeFixed))
{
result = (T)Enum.Parse(typeof(T), strTypeFixed, true);
return true;
}
else
{
foreach (string value in Enum.GetNames(typeof(T)))
{
if (value.Equals(strTypeFixed,
StringComparison.OrdinalIgnoreCase))
{
result = (T)Enum.Parse(typeof(T), value);
return true;
}
}
result = default(T);
return false;
}
}
}
次のように使用します。
public enum TestEnum
{
A,
B,
C
}
public void TestMethod(string StringOfEnum)
{
TestEnum myEnum;
myEnum.TryParse(StringOfEnum, out myEnum);
}
このコードを思いつくために私が訪れた 2 つのサイトは次のとおりです。
別の例を次に示します。一時変数を作成して初期化するよりも優れたIMHOです。
public static class ExtensionMethods
{
public static void ForEach(this Enum enumType, Action<Enum> action)
{
foreach (var type in Enum.GetValues(enumType.GetType()))
{
action((Enum)type);
}
}
}
public enum TestEnum { A,B,C }
public void TestMethod()
{
default(TestEnum).ForEach(Console.WriteLine);
}
次のように変換メソッドを実装することもできます。
public static class Extensions
{
public static ConvertType Convert<ConvertType>(this Enum e)
{
object o = null;
Type type = typeof(ConvertType);
if (type == typeof(int))
{
o = Convert.ToInt32(e);
}
else if (type == typeof(long))
{
o = Convert.ToInt64(e);
}
else if (type == typeof(short))
{
o = Convert.ToInt16(e);
}
else
{
o = Convert.ToString(e);
}
return (ConvertType)o;
}
}
使用例を次に示します。
int a = MyEnum.A.Convert<int>();
列挙型の名前または値に基づいて、ある列挙型から別の列挙型に変換する必要がある場合があります。拡張メソッドを使用してうまく行う方法は次のとおりです。
enum Enum1 { One = 1, Two = 2, Three = 3 };
enum Enum2 { Due = 2, Uno = 1 };
enum Enum3 { Two, One };
Enum2 e2 = Enum1.One.ConvertByValue<Enum2>();
Enum3 e3 = Enum1.One.ConvertByName<Enum3>();
Enum3 x2 = Enum1.Three.ConvertByValue<Enum3>();
public static class EnumConversionExtensions
{
public static T ConvertByName<T>(this Enum value)
{
return (T)Enum.Parse(typeof(T), Enum.GetName(value.GetType(), value));
}
public static T ConvertByValue<T>(this Enum value)
{
return (T)((dynamic)((int)((object)value)));
}
}
Enum 拡張を作成する別の例 - ただし、今回は入力列挙型を返します。
public static IEnumerable<T> toElementsCollection<T>(this T value) where T : struct, IConvertible
{
if (typeof(T).IsEnum == false) throw new Exception("typeof(T).IsEnum == false");
return Enum.GetValues(typeof(T)).Cast<T>();
}
使用例:
public enum TestEnum { A,B,C };
TestEnum.A.toElementsCollection();