【问题标题】: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");
            }
        }
        

        享受吧!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-07-09
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多