用C#制造可以继承的“枚举”

工作中许多代码中用到枚举(enum),更用到了需要继承的枚举,由于C#的枚举不允许被继承(但允许继承自int/float等类型,这个不是我要的,在此不讨论)。

我实现了一个可以继承的模拟枚举,在此与各位分享。
于是我努力制造出可以继承的枚举,确切地说是可以继承的“仿枚举”。

首先要仿System.Enum造一个仿它的地位的类,以“操控一切”。它也是一切可继承枚举的鼻祖。

此类要承担诸多功能:

1.与int/string之间的相互转换

2.支持实例(静态属性)指定或不指定数值

3.一些辅助的功能,如比较大小等

4.一些方便使用的功能,如ForEach方法

5.像string类(class)一样,表现出值传递的效果 

  1  using System;
  2  using System.Collections;
  3  using System.Collections.Generic;
  4 
  5  namespace HeritableEnum
  6 {
  7      public  class HEnum : IComparable<HEnum>, IEquatable<HEnum>
  8     {
  9          static  int counter = - 1;             // 默认数值计数器
 10          private  static Hashtable hashTable =  new Hashtable();        // 不重复数值集合
 11          protected  static List<HEnum> members =  new List<HEnum>();    // 所有实例集合
 12          private  string Name {  getset; }
 13          private  int Value {  getset; }
 14 
 15          ///   <summary>
 16           ///  不指定数值构造实例
 17           ///   </summary>
 18          protected HEnum( string name)
 19         {
 20              this.Name = name;
 21              this.Value = ++counter;
 22             members.Add( this);
 23              if (!hashTable.ContainsKey( this.Value))
 24             {
 25                 hashTable.Add( this.Value,  this);
 26             }
 27         }
 28 
 29          ///   <summary>
 30           ///  指定数值构造实例
 31           ///   </summary>
 32          protected HEnum( string name,  int value)
 33             :  this(name)
 34         {
 35              this.Value = value;
 36             counter = value;
 37         }
 38 
 39          ///   <summary>
 40           ///  向string转换
 41           ///   </summary>
 42           ///   <returns></returns>
 43          public  override  string ToString()
 44         {
 45              return  this.Name.ToString();
 46         }
 47 
 48          ///   <summary>
 49           ///  显式强制从int转换
 50           ///   </summary>
 51           ///   <param name="i"></param>
 52           ///   <returns></returns>
 53          public  static  explicit  operator HEnum( int i)
 54         {
 55              if (hashTable.ContainsKey(i))
 56             {
 57                  return (HEnum)members[i];
 58             }
 59              return  new HEnum(i.ToString(), i);
 60         }
 61 
 62          ///   <summary>
 63           ///  显式强制向int转换
 64           ///   </summary>
 65           ///   <param name="e"></param>
 66           ///   <returns></returns>
 67          public  static  explicit  operator  int(HEnum e)
 68         {
 69              return e.Value;
 70         }
 71 
 72          public  static  void ForEach(Action<HEnum> action)
 73         {
 74              foreach (HEnum item  in members)
 75             {
 76                 action(item);
 77             }
 78         }
 79 
 80          public  int CompareTo(HEnum other)
 81         {
 82              return  this.Value.CompareTo(other.Value);
 83         }
 84 
 85          public  bool Equals(HEnum other)
 86         {
 87              return  this.Value.Equals(other.Value);
 88         }
 89 
 90          public  override  bool Equals( object obj)
 91         {
 92              if (!(obj  is HEnum))
 93                  return  false;
 94              return  this.Value == ((HEnum)obj).Value;
 95         }
 96 
 97          public  override  int GetHashCode()
 98         {
 99             HEnum std = (HEnum)hashTable[ this.Value];
100              if (std.Name ==  this.Name)
101                  return  base.GetHashCode();
102              return std.GetHashCode();
103         }
104 
105          public  static  bool  operator !=(HEnum e1, HEnum e2)
106         {
107              return e1.Value != e2.Value;
108         }
109 
110          public  static  bool  operator <(HEnum e1, HEnum e2)
111         {
112              return e1.Value < e2.Value;
113         }
114 
115          public  static  bool  operator <=(HEnum e1, HEnum e2)
116         {
117              return e1.Value <= e2.Value;
118         }
119 
120          public  static  bool  operator ==(HEnum e1, HEnum e2)
121         {
122              return e1.Value == e2.Value;
123         }
124 
125          public  static  bool  operator >(HEnum e1, HEnum e2)
126         {
127              return e1.Value > e2.Value;
128         }
129 
130          public  static  bool  operator >=(HEnum e1, HEnum e2)
131         {
132              return e1.Value >= e2.Value;
133         }
134     }
135 }

 

经过时间跨度很长中的N次尝试后,写成了上面这个样子,实现了最基本的功能。ForEach后面都是直接或间接为了“比较大小”要写的方法。

值得强调的是此类的所有构造方法必须是protected,以防止在类之外构造实例。它的子类也必须这样,以下是用于演示的子类:

 

class EnumUse1 : HEnum
{
     protected EnumUse1( string name) :  base(name) { }

     protected EnumUse1( string name,  int value) :  base(name, value) { }

     public  static EnumUse1 A =  new EnumUse1( " A ");
     public  static EnumUse1 B =  new EnumUse1( " B "2);
     public  static EnumUse1 C =  new EnumUse1( " C "2);
     public  static EnumUse1 D =  new EnumUse1( " D ");
}

EnumUse1从HEnum继承,模拟以下的代码

enum EnumUse1
{
    A,
    B =  2,
    C =  2,
    D
}

再有一个子类从EnumUse1继承:

class EnumUse2 : EnumUse1
{
     protected EnumUse2( string name) :  base(name) { }

     protected EnumUse2( string name,  int value) :  base(name, value) { }

     public  static EnumUse2 E =  new EnumUse2( " E ");
}

用起来跟系统原生的enum很像

class Program
{
     static  void Main( string[] args)
    {
         bool b = EnumUse1.D >= EnumUse1.A;
        Console.WriteLine(b.ToString());
        Show(EnumUse2.E);
        HEnum.ForEach((x) => Console.WriteLine( " {0} = {1}, ", x, ( int)x));
    }

     static  void Show(HEnum e)
    {
        Console.WriteLine( @" {0} = {1},""{2}"" ", e, ( int)e, e.ToString());
    }
}

看,现在做到了可以比较大小,可以转化成string,(从string转回暂未做,但也不难),可以与int互转,值传递的效果(演示中无体现)。还比原生的enum多了ForEach功能,这点很方便。运行结果:

True

E = 4,"E"

A = 0,

B = 2,

C = 2,

D = 3,

E = 4,

话说回来,此类还有诸多不足,充其量只能算是一个实验品,想要真正走向实用,还有些工作要做。在此发布,纪念此次实验及成果。

 

转载于:https://www.cnblogs.com/BillySir/archive/2012/02/15/2353395.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值