在vs2008中,是否可以编写适用于任何枚举的扩展方法。
我知道你可以针对特定的枚举编写扩展方法,但我希望能够使用单个扩展方法进行每个枚举。这可能吗?
答案 0 :(得分:81)
是的,只需针对基础Enum
类型的代码,例如
public static void Something(this Enum e)
{
// code here
}
缺点是你最终可能会做一些非常讨厌的事情,例如使用Enum.GetUnderlyingType
查找真实的基类型,转换,并根据枚举的基本类型向下走不同的分支,但是你可以找到它的一些好的用途(例如我们有适用于所有枚举的IsOneOf
和IsCombinationOf
方法。)
float
和double
作为枚举的基本类型,因此您需要一些特殊情况以及无符号值。
答案 1 :(得分:18)
是的,你可以。目标扩展类型的类型为Enum
。在C#中,这将完成:
public static void EnumExtension(this Enum e)
{
}
或在VB中这样:
<Extension()> _
Public Sub EnumExtension(ByVal s As Enum)
End Sub
答案 2 :(得分:18)
FYI这是我能够使用的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);
}
以下是我访问过的两个网站,以帮助您提供此代码:
答案 3 :(得分:9)
这是另一个例子 - 也比不得不创建和初始化临时变量更好的恕我直言。
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);
}
答案 4 :(得分:4)
您还可以按如下方式实现转换方法:
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>();
答案 5 :(得分:2)
有时需要根据枚举的名称或值从一个枚举转换为另一个枚举。以下是如何使用扩展方法很好地完成它:
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)));
}
}
答案 6 :(得分:1)
制作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();