利用C#實現(xiàn)可以繼承的"枚舉"
工作中許多代碼中用到枚舉(enum),更用到了需要繼承的枚舉,由于C#的枚舉不允許被繼承(但允許繼承自int/float等類型,這個不是我要的,在此不討論)。
我實現(xiàn)了一個可以繼承的模擬枚舉,在此與各位分享。
于是我努力制造出可以繼承的枚舉,確切地說是可以繼承的“仿枚舉”。
首先要仿System.Enum造一個仿它的地位的類,以“操控一切”。它也是一切可繼承枚舉的鼻祖。
此類要承擔(dān)諸多功能:
1.與int/string之間的相互轉(zhuǎn)換
2.支持實例(靜態(tài)屬性)指定或不指定數(shù)值
3.一些輔助的功能,如比較大小等
4.一些方便使用的功能,如ForEach方法
5.像string類(class)一樣,表現(xiàn)出值傳遞的效果
using System;
using System.Collections;
using System.Collections.Generic;
namespace HeritableEnum
{
public class HEnum : IComparable<HEnum>, IEquatable<HEnum>
{
static int counter = -1; //默認(rèn)數(shù)值計數(shù)器
private static Hashtable hashTable = new Hashtable(); //不重復(fù)數(shù)值集合
protected static List<HEnum> members = new List<HEnum>(); //所有實例集合
private string Name { get; set; }
private int Value { get; set; }
/// <summary>
/// 不指定數(shù)值構(gòu)造實例
/// </summary>
protected HEnum(string name)
{
this.Name = name;
this.Value = ++counter;
members.Add(this);
if (!hashTable.ContainsKey(this.Value))
{
hashTable.Add(this.Value, this);
}
}
/// <summary>
/// 指定數(shù)值構(gòu)造實例
/// </summary>
protected HEnum(string name, int value)
: this(name)
{
this.Value = value;
counter = value;
}
/// <summary>
/// 向string轉(zhuǎn)換
/// </summary>
/// <returns></returns>
public override string ToString()
{
return this.Name.ToString();
}
/// <summary>
/// 顯式強制從int轉(zhuǎn)換
/// </summary>
/// <param name="i"></param>
/// <returns></returns>
public static explicit operator HEnum(int i)
{
if (hashTable.ContainsKey(i))
{
return (HEnum)members[i];
}
return new HEnum(i.ToString(), i);
}
/// <summary>
/// 顯式強制向int轉(zhuǎn)換
/// </summary>
/// <param name="e"></param>
/// <returns></returns>
public static explicit operator int(HEnum e)
{
return e.Value;
}
public static void ForEach(Action<HEnum> action)
{
foreach (HEnum item in members)
{
action(item);
}
}
public int CompareTo(HEnum other)
{
return this.Value.CompareTo(other.Value);
}
public bool Equals(HEnum other)
{
return this.Value.Equals(other.Value);
}
public override bool Equals(object obj)
{
if (!(obj is HEnum))
return false;
return this.Value == ((HEnum)obj).Value;
}
public override int GetHashCode()
{
HEnum std = (HEnum)hashTable[this.Value];
if (std.Name == this.Name)
return base.GetHashCode();
return std.GetHashCode();
}
public static bool operator !=(HEnum e1, HEnum e2)
{
return e1.Value != e2.Value;
}
public static bool operator <(HEnum e1, HEnum e2)
{
return e1.Value < e2.Value;
}
public static bool operator <=(HEnum e1, HEnum e2)
{
return e1.Value <= e2.Value;
}
public static bool operator ==(HEnum e1, HEnum e2)
{
return e1.Value == e2.Value;
}
public static bool operator >(HEnum e1, HEnum e2)
{
return e1.Value > e2.Value;
}
public static bool operator >=(HEnum e1, HEnum e2)
{
return e1.Value >= e2.Value;
}
}
}經(jīng)過時間跨度很長中的N次嘗試后,寫成了上面這個樣子,實現(xiàn)了最基本的功能。ForEach后面都是直接或間接為了“比較大小”要寫的方法。
值得強調(diào)的是此類的所有構(gòu)造方法必須是protected,以防止在類之外構(gòu)造實例。它的子類也必須這樣,以下是用于演示的子類:
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");
}用起來跟系統(tǒng)原生的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());
}
}看,現(xiàn)在做到了可以比較大小,可以轉(zhuǎn)化成string,(從string轉(zhuǎn)回暫未做,但也不難),可以與int互轉(zhuǎn),值傳遞的效果(演示中無體現(xiàn))。還比原生的enum多了ForEach功能,這點很方便。運行結(jié)果:
True
E = 4,"E"
A = 0,
B = 2,
C = 2,
D = 3,
E = 4,
話說回來,此類還有諸多不足,充其量只能算是一個實驗品,想要真正走向?qū)嵱茫€有些工作要做。在此發(fā)布,紀(jì)念此次實驗及成果。
到此這篇關(guān)于利用C#實現(xiàn)可以繼承的"枚舉"的文章就介紹到這了,更多相關(guān)C#枚舉內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#實現(xiàn)Excel轉(zhuǎn)PDF時設(shè)置內(nèi)容適應(yīng)頁面寬度
將Excel轉(zhuǎn)為PDF格式時,通常情況下轉(zhuǎn)換出來的PDF頁面都是默認(rèn)的寬度大小。所以本文提供了C#實現(xiàn)Excel轉(zhuǎn)PDF時設(shè)置內(nèi)容適應(yīng)頁面寬度的示例代碼,需要的可以參考一下2022-04-04
C# WinForm創(chuàng)建Excel文件的實例
下面小編就為大家?guī)硪黄狢# WinForm創(chuàng)建Excel文件的實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-01-01
C#獲取所有SQL Server數(shù)據(jù)庫名稱的方法
這篇文章主要介紹了C#獲取所有SQL Server數(shù)據(jù)庫名稱的方法,涉及C#針對sql server數(shù)據(jù)庫的簡單查詢技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-08-08

