
bald
Ich weiß, dass dies eher gegen die Idee von Aufzählungen verstößt, aber ist es möglich, Aufzählungen in C#/Java zu erweitern? Ich meine “erweitern” sowohl im Sinne des Hinzufügens neuer Werte zu einer Aufzählung, als auch im OO-Sinne des Erbens von einer bestehenden Aufzählung.
Ich gehe davon aus, dass dies in Java nicht möglich ist, da es sie erst vor relativ kurzer Zeit erhalten hat (Java 5?). C# scheint jedoch Leuten, die verrückte Dinge tun wollen, nachsichtiger zu sein, also dachte ich, dass es irgendwie möglich sein könnte. Vermutlich könnte es durch Reflektion gehackt werden (nicht, dass Sie diese Methode tatsächlich verwenden würden)?
Ich bin nicht unbedingt daran interessiert, eine bestimmte Methode zu implementieren, es hat nur meine Neugier geweckt, als es mir einfiel 🙂
Der Grund, warum Sie Enums nicht erweitern können, liegt darin, dass dies zu Problemen mit Polymorphismus führen würde.
Angenommen, Sie haben eine Aufzählung MyEnum mit den Werten A, B und C und erweitern sie mit dem Wert D als MyExtEnum.
Angenommen, eine Methode erwartet irgendwo einen myEnum-Wert, beispielsweise als Parameter. Es sollte legal sein, einen MyExtEnum-Wert anzugeben, da es sich um einen Untertyp handelt, aber was werden Sie jetzt tun, wenn sich herausstellt, dass der Wert D ist?
Um dieses Problem zu beseitigen, ist das Erweitern von Aufzählungen illegal

Zimon
Wenn integrierte Aufzählungen nicht ausreichen, können Sie es auf die altmodische Weise tun und Ihre eigenen erstellen. Wenn Sie beispielsweise eine zusätzliche Eigenschaft hinzufügen möchten, z. B. ein Beschreibungsfeld, können Sie dies wie folgt tun:
public class Action {
public string Name {get; private set;}
public string Description {get; private set;}
private Action(string name, string description) {
Name = name;
Description = description;
}
public static Action DoIt = new Action("Do it", "This does things");
public static Action StopIt = new Action("Stop It", "This stops things");
}
Sie können es dann wie eine Aufzählung behandeln:
public void ProcessAction(Action a) {
Console.WriteLine("Performing action: " + a.Name)
if (a == Action.DoIt) {
// ... and so on
}
}
Der Trick besteht darin, sicherzustellen, dass der Konstruktor privat ist (oder geschützt ist, wenn Sie erben möchten) und dass Ihre Instanzen statisch sind.
Sie gehen in die falsche Richtung: Eine Unterklasse einer Aufzählung hätte weniger Einträge.
Denken Sie in Pseudocode:
enum Animal { Mosquito, Dog, Cat };
enum Mammal : Animal { Dog, Cat }; // (not valid C#)
Jede Methode, die ein Tier akzeptieren kann, sollte ein Säugetier akzeptieren können, aber nicht umgekehrt. Subclassing dient dazu, etwas spezifischer zu machen, nicht allgemeiner. Deshalb ist “Objekt” die Wurzel der Klassenhierarchie. Wenn Aufzählungen vererbbar wären, hätte eine hypothetische Wurzel der Aufzählungshierarchie jedes mögliche Symbol.
Aber nein, C#/Java erlaubt keine Unteraufzählungen, AFAICT, obwohl es manchmal wirklich nützlich wäre. Das liegt wahrscheinlich daran, dass sie sich dafür entschieden haben, Enums als Ints (wie C) anstelle von internierten Symbolen (wie Lisp) zu implementieren. (Oben, was stellt (Tier)1 dar und was stellt (Säugetier)1 dar, und haben sie denselben Wert?)
Sie könnten jedoch Ihre eigene enum-ähnliche Klasse (mit einem anderen Namen) schreiben, die dies bereitstellt. Mit C#-Attributen sieht es vielleicht sogar nett aus.
Aufzählungen sollen die Aufzählung aller möglichen Werte darstellen, daher widerspricht das Erweitern eher der Idee.
Was Sie jedoch in Java (und vermutlich C++0x) tun können, ist eine Schnittstelle anstelle einer Aufzählungsklasse. Setzen Sie dann Ihre Standardwerte in eine Aufzählung, die die Funktion implementiert. Offensichtlich können Sie java.util.EnumSet und dergleichen nicht verwenden. Dies ist der Ansatz, der in “mehr NIO-Funktionen” verfolgt wird, die in JDK7 enthalten sein sollten.
public interface Result {
String name();
String toString();
}
public enum StandardResults implements Result {
TRUE, FALSE
}
public enum WTFResults implements Result {
FILE_NOT_FOUND
}
Sie können die .NET-Reflektion verwenden, um die Beschriftungen und Werte zur Laufzeit aus einer vorhandenen Aufzählung abzurufen (Enum.GetNames()
und Enum.GetValues()
sind die beiden spezifischen Methoden, die Sie verwenden würden) und verwenden Sie dann die Code-Injektion, um eine neue mit diesen Elementen und einigen neuen zu erstellen. Dies scheint etwas analog zu “Erben von einer vorhandenen Aufzählung” zu sein.

Darrell Denlinger
Ich habe niemanden gesehen, der dies erwähnt hat, aber der Ordinalwert einer Aufzählung ist wichtig. Wenn Sie beispielsweise mit Grails eine Aufzählung in der Datenbank speichern, verwendet sie den Ordinalwert. Wenn Sie eine Aufzählung irgendwie erweitern könnten, was wären die Ordnungswerte Ihrer Erweiterungen? Wenn Sie es an mehreren Stellen erweitern, wie könnten Sie diese Ordnungszahlen irgendwie ordnen? Chaos/Instabilität in den Ordinalwerten wäre eine schlechte Sache, was wahrscheinlich ein weiterer Grund ist, warum die Sprachdesigner dies nicht berührt haben.
Eine weitere Schwierigkeit, wenn Sie der Sprachdesigner wären, wie können Sie die Funktionalität der Methode values() beibehalten, die alle Enum-Werte zurückgeben soll. Wofür würden Sie das aufrufen und wie würde es alle Werte erfassen?

Oskar
Das Hinzufügen von Aufzählungen ist eine ziemlich übliche Sache, wenn Sie zum Quellcode zurückkehren und ihn bearbeiten, jede andere Methode (Vererbung oder Reflektion, falls beides möglich ist) wird wahrscheinlich zurückkommen und Sie treffen, wenn Sie ein Upgrade der Bibliothek und erhalten Sie haben den gleichen Aufzählungsnamen eingeführt oder der gleiche Enum-Wert – Ich habe viel Lowlevel-Code gesehen, bei dem die Ganzzahl mit der binären Codierung übereinstimmt, bei der Sie auf Probleme stoßen würden
Idealerweise sollte Code, der Aufzählungen referenziert, nur als Gleichheit (oder Schalter) geschrieben werden, und versuchen Sie, zukunftssicher zu sein, indem Sie nicht erwarten, dass die Aufzählungsmenge konstant ist
9976600cookie-checkErweitern einer Aufzählung durch Vererbungyes
Beantwortet das deine Frage? Enum “Vererbung”
– T. Todua
30. Oktober 2019 um 17:02 Uhr