Hattet ihr auch schon einmal das Problem, dass ihr in eurer Software eine Enumeration verwenden wolltet, aber eigentlich zwei Enumeration benötigt wurden, weil ein anderer Programmteil mehr Werte benötigt? Ich schon :-). In meinem Fall ging es um Messbereiche von unterschiedlichen Hardwaregeräten. Zum Beispiel besitzt Gerät A die Messbereiche „Low“ und „High“, während Gerät B die Messbereiche „Low“, „High“, „Medium“ und „Aux“. Der Entwickler soll in seinem Programm aber nicht mit der Hardwareabhängigkeit konfrontiert werden und wählt über den Namespace das entsprechende Gerät und damit auch die Implementierung der Enumeration.
Da „Low“ und „High“ die gemeinsamen Messbereiche abbilden, werden sie in der Hauptklasse verwendet, von der alle Erweiterungen dann ableiten. Der eigentliche Trick besteht aber darin, dass diese Klasse statische Klassenvariablen anbietet, die nur innerhalb dieser Klasse und ihrer Ableitungen initialisiert werden können. Überläd man außerdem noch die Operatoren kann man auch einfach die Werte miteinander vergleichen. Hier ein Beispiel, wie diese Klasse aussehen könnte:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
public class MeasurementRange { public static MeasurementRange Low = new MeasurementRange(0); public static MeasurementRange High = new MeasurementRange(1); public int Value { get; private set; } protected MeasurementRange(int value) { Value = value; } public static bool operator== (MeasurementRange range1, MeasurementRange range2) { if (ReferenceEquals(range1, null) || ReferenceEquals(range2, null)) { return false; } if (range1.Value == range2.Value) { return true; } return false; } public static bool operator !=(MeasurementRange range1, MeasurementRange range2) { if (ReferenceEquals(range1, null) || ReferenceEquals(range2, null)) { return false; } if (range1.Value != range2.Value) { return false; } return false; } public override int GetHashCode() { return Value.GetHashCode(); } public override bool Equals(object obj) { if (obj == null || GetType() != obj.GetType()) { return false; } var range = (MeasurementRange)obj; return (Value == range.Value); } } |
Möchte man diese Klasse nun erweitern, braucht man nur eine neue Klasse anlegen, die von dieser Klasse ableitet und den Konstruktor der Basisklasse aufrufen. Hier das Beispiel für das oben genannte Gerät B:
1 2 3 4 5 6 7 8 9 |
public class MeasurementRangeDeviceB : MeasurementRange { public static MeasurementRange Medium = new MeasurementRangeDeviceB(2); public static MeasurementRange Aux = new MeasurementRangeDeviceB(3); private MeasurementRangeDeviceB(int value) : base(value) { } } |
Im Hauptprogramm kann man jetzt einfach eine Variable vom Typ „MeasurementRange“ deklarieren und die statischen Variablen der beiden Klassen zuweisen. Dabei ist es vollkommen egal, von welcher Klasse die statischen Variablen herkommen. Nachfolgend ein paar Zeilen Programmcode, die das auch noch verdeutlichen:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
//Device A (generic) MeasurementRange range = MeasurementRange.Low; Console.WriteLine("Value = {0}, Equals = {1}", range.Value, MeasurementRange.Low == range); range = MeasurementRange.High; Console.WriteLine("Value = {0}, Equals = {1}", range.Value, MeasurementRange.High == range); //Device B range = MeasurementRangeDeviceB.Low; Console.WriteLine("Value = {0}, Equals = {1}", range.Value, MeasurementRangeDeviceB.Low == range); range = MeasurementRangeDeviceB.High; Console.WriteLine("Value = {0}, Equals = {1}", range.Value, MeasurementRangeDeviceB.High == range); range = MeasurementRangeDeviceB.Medium; Console.WriteLine("Value = {0}, Equals = {1}", range.Value, MeasurementRangeDeviceB.Medium == range); range = MeasurementRangeDeviceB.Aux; Console.WriteLine("Value = {0}, Equals = {1}", range.Value, MeasurementRangeDeviceB.Aux == range); |
Für unsere Implementierung war das genau der richtige Ansatz. Solltet ihr das Extendable Enum in einem eurer Projekte einsetzen oder andere (elegantere?) Ansätze für das Problem haben, dann schreibt doch einen Kommentar. Würde mich freuen :-).