In my work, enums are used in many codes, and enums that need to be inherited. Since enums in C# are not allowed to be inherited (but are allowed to inherit from int/float and other types, this is not what I want, so I won't discuss it here).
I have implemented an inheritable mock enumeration, and I will share it with you here.
So I worked hard to create an enum that can be inherited, or to be precise, an "imitation enum" that can be inherited.
First, we must imitate a class that imitates its status to "manipulate everything". It is also the originator of all inheritable enumerations.
This type of function takes on many functions:
1. Mutual conversion with int/string
2. Supports instance (static attribute) to specify or not specify numeric values
3. Some auxiliary functions, such as comparing sizes, etc.
4. Some convenient functions, such as the ForEach method
5. Like the string class, it shows the effect of value transfer.
using System; using ; using ; namespace HeritableEnum { public class HEnum : IComparable<HEnum>, IEquatable<HEnum> { static int counter = -1; //Default numerical counter private static Hashtable hashTable = new Hashtable(); //Do not repeat the numerical set protected static List<HEnum> members = new List<HEnum>(); //All instance collections private string Name { get; set; } private int Value { get; set; } /// <summary> /// No numerical constructing example /// </summary> protected HEnum(string name) { = name; = ++counter; (this); if (!()) { (, this); } } /// <summary> /// Specify numerical construction example /// </summary> protected HEnum(string name, int value) : this(name) { = value; counter = value; } /// <summary> /// Convert to string /// </summary> /// <returns></returns> public override string ToString() { return (); } /// <summary> /// explicitly force conversion from int /// </summary> /// <param name="i"></param> /// <returns></returns> public static explicit operator HEnum(int i) { if ((i)) { return (HEnum)members[i]; } return new HEnum((), i); } /// <summary> /// Explicitly force conversion to int /// </summary> /// <param name="e"></param> /// <returns></returns> public static explicit operator int(HEnum e) { return ; } public static void ForEach(Action<HEnum> action) { foreach (HEnum item in members) { action(item); } } public int CompareTo(HEnum other) { return (); } public bool Equals(HEnum other) { return (); } public override bool Equals(object obj) { if (!(obj is HEnum)) return false; return == ((HEnum)obj).Value; } public override int GetHashCode() { HEnum std = (HEnum)hashTable[]; if ( == ) return (); return (); } public static bool operator !=(HEnum e1, HEnum e2) { return != ; } public static bool operator <(HEnum e1, HEnum e2) { return < ; } public static bool operator <=(HEnum e1, HEnum e2) { return <= ; } public static bool operator ==(HEnum e1, HEnum e2) { return == ; } public static bool operator >(HEnum e1, HEnum e2) { return > ; } public static bool operator >=(HEnum e1, HEnum e2) { return >= ; } } }
After N attempts with a long time span, the above is written as shown, realizing the most basic function. After ForEach, the methods to be written directly or indirectly for "comparing the size".
It is worth stressing that all constructors of this class must be protected to prevent instances from being constructed outside the class. Its subclass must also be like this, and the following are the subclasses used for demonstration:
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 inherits from HEnum, mocking the following code
enum EnumUse1 { A, B = 2, C = 2, D }
Another subclass inherits from 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"); }
It's very similar to the system native enum
class Program { static void Main(string[] args) { bool b = >= ; (()); Show(); ((x) => ("{0} = {1},", x, (int)x)); } static void Show(HEnum e) { (@"{0} = {1},""{2}""", e, (int)e, ()); } }
Look, now it can be compared with the size and can be converted into string (turning from string back to not done yet, but it is not difficult), and can be transferred with int, and the effect of value transfer (not reflected in the demonstration). It also has more ForEach function than native enums, which is very convenient. Running results:
True
E = 4,"E"
A = 0,
B = 2,
C = 2,
D = 3,
E = 4,
Having said that, there are still many shortcomings in this type, which can only be regarded as an experimental product at best. If you want to truly become practical, there is still some work to be done. This is published here to commemorate the experiment and results.
This is the end of this article about using C# to implement "enumerations" that can be inherited. For more related C# enumeration content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!