在vs2008中,是否可以编写一个扩展方法,使其适用于任何枚举类型?
我知道你可以针对特定枚举类型编写扩展方法,但我想能够使用单个扩展方法来处理每个枚举类型。这是可能的吗?
我知道你可以针对特定枚举类型编写扩展方法,但我想能够使用单个扩展方法来处理每个枚举类型。这是可能的吗?
是的,只需针对基本的 Enum
类型编写代码,例如:
public static void Something(this Enum e)
{
// code here
}
缺点是您可能需要执行一些比较恶心的工作,例如使用Enum.GetUnderlyingType
查找实际基本类型,进行强制类型转换,根据enum的基本类型走不同的分支路线,但是您可以找到一些很好的用途(例如我们有适用于所有枚举类型的IsOneOf
和IsCombinationOf
方法)。
PS:在编写该方法时,请记住,虽然不建议,但您可以将float
和double
用作枚举类型的基本类型,因此您还需要针对这些类型以及无符号值进行一些特殊处理。
提供一份很好的枚举扩展方法示例,可以实现不区分大小写的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);
}
以下是我访问的两个网站,以帮助编写此代码:
可以。目标扩展类型是Enum
类型。在C#中,可以这样做:
public static void EnumExtension(this Enum e)
{
}
或者在VB中这样写:
<Extension()> _
Public Sub EnumExtension(ByVal s As Enum)
End Sub
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);
}
default(TestEnum)
创建的是一个匿名且立即进行垃圾回收的实例,但您仍然在创建枚举的临时实例。值得指出的是,扩展方法如果没有正在扩展的实例就无法正常工作,因此我们能够做到的最接近的方法是实例化枚举类型本身并从该类型进行扩展方法。请参阅https://dev59.com/D3E95IYBdhLWcg3wKq6q,了解一种有趣的实现方式。 - MushinNoShinpublic 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
都实现了 IConvertible
。 - John Alexiouenum 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)));
}
}
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();