【问题标题】:Extension and enum type扩展和枚举类型
【发布时间】:2013-02-12 07:53:31
【问题描述】:
我正在尝试将扩展方法添加到 Enum 类型,但下面的代码失败。编译器在StoreType.GetAllItems行报错如何给Enum类型添加扩展方法?
namespace ConsoleApplication1
{
public static class EnumExtensions
{
public static IEnumerable<T> GetAllItems<T>(this Enum value)
{
foreach (object item in Enum.GetValues(typeof(T)))
{
yield return (T)item;
}
}
}
class Program
{
[Flags]
public enum StoreType
{
Paypal = 1,
Plimus = 2,
Other = 3
};
static void Main(string[] args)
{
StoreType.GetAllItems //Fail here
}
}
}
【问题讨论】:
标签:
c#-4.0
enums
extension-methods
【解决方案1】:
你必须在一个值上调用 GetAllItems,而不是一个类型:
StoreType.Paypal.GetAllItems()
但是最好不要让它成为扩展方法并声明为:
public static class EnumExtensions
{
public static IEnumerable<T> GetAllItems<T>()
{
foreach (object item in Enum.GetValues(typeof(T)))
{
yield return (T)item;
}
}
}
static void Main(string[] args)
{
var allEnumItems = EnumExtensions.GetAllItems<StoreType>()
}
甚至:
Enum.GetValues(typeof (StoreType));
Enum.GetNames(typeof (StoreType));
之后您可以使用 Enum.TryParse(...) 将名称解析回枚举,我认为这就是您想要的吗?
【解决方案2】:
您会看到编译器错误,因为您无法覆盖默认 c# enum,根据 to this article 尝试通过将您的方法添加到自定义类来覆盖您的枚举:
public class MyEnum
{
public static readonly MyEnum A = new MyEnum("A");
public static readonly MyEnum B = new MyEnum("B");
public static readonly MyEnum C = new MyEnum("C");
public static IEnumerable<T> GetAllItems<T>(this Enum value)
{
foreach (object item in Enum.GetValues(typeof(T)))
{
yield return (T)item;
}
}
public override string ToString()
{
return Value;
}
protected MyEnum(string value)
{
this.Value = value;
}
public string Value { get; private set; }
}
public sealed class MyDerivedEnum : MyEnum
{
public static readonly MyDerivedEnum D = new MyDerivedEnum("D");
private MyDerivedEnum(string value)
: base(value)
{
}
}
class Program
{
static void Main(string[] args)
{
MyEnum blah = MyEnum.A;
System.Console.WriteLine(blah);
blah = MyDerivedEnum.D;
System.Console.WriteLine(blah);
}
}
【解决方案3】:
我会说那将是一个带有伪扩展的类。它可能看起来像这样:
用法:
List<HttpStatusCode> list = EnumUtils<HttpStatusCode>.ToList();
Dictionary<int, HttpStatusCode> map = EnumUtils<HttpStatusCode>.ToDictionary();
伪扩展类:
/// <summary>Pseudo extension class for enumerations</summary>
/// <typeparam name="TEnum">Enumeration type</typeparam>
public class EnumUtils<TEnum> where TEnum : struct, IConvertible
{
public static List<TEnum> ToList()
{
var enumType = typeof(TEnum);
return enumType.IsEnum
? enumType.GetEnumValues().OfType<TEnum>().ToList()
: throw new ArgumentException($"{enumType.Name} is not enum");
}
public static Dictionary<int, TEnum> ToDictionary()
{
Type enumType = typeof(TEnum);
return enumType.IsEnum
? enumType.GetEnumValues().OfType<TEnum>().ToDictionary(
e => Convert.ToInt32(Enum.Parse(typeof(TEnum), e.ToString()) as Enum),
e => e)
: throw new ArgumentException($"{enumType.Name} is not enum");
}
}
享受吧!