Ich habe eine Weile in Java programmiert und bin gerade auf ein Projekt gestoßen, das vollständig in C # geschrieben ist. Ich versuche, mich in C # auf den neuesten Stand zu bringen, und habe festgestellt, dass in meinem neuen Projekt an mehreren Stellen Aufzählungen verwendet werden. Auf den ersten Blick scheinen die Aufzählungen in C # jedoch einfacher zu sein als die Implementierung von Java 1.5+. Kann jemand die Unterschiede zwischen C # - und Java-Enums aufzählen und wie man die Unterschiede überwindet? (Ich möchte keinen Sprachflammenkrieg beginnen, ich möchte nur wissen, wie man einige Dinge in C # macht, die ich früher in Java gemacht habe). Könnte zum Beispiel jemand ein C # -Gleichstück zu Suns berühmtem Planet-Enum-Beispiel posten?
public enum Planet {
MERCURY (3.303e+23, 2.4397e6),
VENUS (4.869e+24, 6.0518e6),
EARTH (5.976e+24, 6.37814e6),
MARS (6.421e+23, 3.3972e6),
JUPITER (1.9e+27, 7.1492e7),
SATURN (5.688e+26, 6.0268e7),
URANUS (8.686e+25, 2.5559e7),
NEPTUNE (1.024e+26, 2.4746e7),
PLUTO (1.27e+22, 1.137e6);
private final double mass; // in kilograms
private final double radius; // in meters
Planet(double mass, double radius) {
this.mass = mass;
this.radius = radius;
}
public double mass() { return mass; }
public double radius() { return radius; }
// universal gravitational constant (m3 kg-1 s-2)
public static final double G = 6.67300E-11;
public double surfaceGravity() {
return G * mass / (radius * radius);
}
public double surfaceWeight(double otherMass) {
return otherMass * surfaceGravity();
}
}
// Example usage (slight modification of Sun's example):
public static void main(String[] args) {
Planet pEarth = Planet.EARTH;
double earthRadius = pEarth.radius(); // Just threw it in to show usage
// Argument passed in is earth Weight. Calculate weight on each planet:
double earthWeight = Double.parseDouble(args[0]);
double mass = earthWeight/pEarth.surfaceGravity();
for (Planet p : Planet.values())
System.out.printf("Your weight on %s is %f%n",
p, p.surfaceWeight(mass));
}
// Example output:
$ java Planet 175
Your weight on MERCURY is 66.107583
Your weight on VENUS is 158.374842
[etc ...]
quelle
Antworten:
Aufzählungen in der CLR werden einfach als Konstanten bezeichnet. Der zugrunde liegende Typ muss ganzzahlig sein. In Java ähnelt eine Aufzählung eher einer benannten Instanz eines Typs. Dieser Typ kann sehr komplex sein und - wie Ihr Beispiel zeigt - mehrere Felder verschiedener Typen enthalten.
Um das Beispiel auf C # zu portieren, würde ich einfach die Aufzählung in eine unveränderliche Klasse ändern und statische schreibgeschützte Instanzen dieser Klasse verfügbar machen:
quelle
In C # können Sie definieren Erweiterungsmethoden für Aufzählungen Dies gleicht einige der fehlenden Funktionen aus.
Sie können
Planet
als Aufzählung definieren und haben auch Erweiterungsmethoden, diesurfaceGravity()
und entsprechensurfaceWeight()
.Ich habe benutzerdefinierte Attribute verwendet, wie von Mikhail vorgeschlagen , aber das gleiche könnte mit einem Wörterbuch erreicht werden.
quelle
In C # können Attribute mit Aufzählungen verwendet werden. Ein gutes Beispiel für dieses Programmiermuster mit detaillierter Beschreibung finden Sie hier (Codeproject).
Bearbeiten: Diese Frage wurde kürzlich erneut gestellt und von Jon Skeet beantwortet: Was entspricht Javas Aufzählung in C #? Private innere Klassen in C # - warum werden sie nicht häufiger verwendet?
Bearbeiten 2: Sehen Sie die akzeptierte Antwort, die diesen Ansatz auf sehr brillante Weise erweitert!
quelle
Java-Aufzählungen sind eigentlich vollständige Klassen, die einen privaten Konstruktor und Methoden usw. haben können, während C # -Aufzählungen nur als Ganzzahlen bezeichnet werden. Die Implementierung von IMO Java ist weit überlegen.
Diese Seite sollte Ihnen beim Lernen von c # aus einem Java-Camp sehr helfen. (Der Link verweist auf die Unterschiede bei den Aufzählungen (für andere Dinge nach oben / unten scrollen)
quelle
FOO = 0
in ORM-Tools einfacher zu verwenden ist (keine fehleranfälligeordinal()
Verwendung erforderlich). Weiteres C # unterstützt bitweise Aufzählungen, die oft sehr nützlich sind, insbesondere in Kombination mitEntityFramework
. Java sollte ihre Aufzählungen erweitern, damit sie auch an Ganzzahlen gebunden werden können. Dann wären sie überlegen :)So etwas denke ich:
Oder kombinieren Sie die Konstanten
Planet
wie oben in der Klassequelle
Hier ist eine weitere interessante Idee, die das in Java verfügbare benutzerdefinierte Verhalten berücksichtigt. Ich habe mir folgende
Enumeration
Basisklasse ausgedacht:Es hat im Grunde genommen einen Typparameter, damit die Ordnungszahl für verschiedene abgeleitete Aufzählungen ordnungsgemäß funktioniert. Das
Operator
Beispiel von Jon Skeet aus seiner Antwort auf eine andere Frage (http://stackoverflow.com/questions/1376312/whats-the-equivalent-of-javas-enum-in-c) oben lautet dann:Dies bietet einige Vorteile.
string
undint
macht switch-Anweisungen möglichSystem.Enum
können zur Basis-Enumerationsklasse hinzugefügt werden, um dieselbe Funktionalität zu ermöglichen.quelle
Wir haben gerade eine Enum-Erweiterung für c # erstellt https://github.com/simonmau/enum_ext erstellt
Es ist nur eine Implementierung für das Typensafeenum, aber es funktioniert großartig, also haben wir ein Paket zum Teilen erstellt - viel Spaß damit
quelle
Eine Java-Aufzählung ist syntaktischer Zucker, um Aufzählungen auf OO-Weise darzustellen. Es handelt sich um abstrakte Klassen, die die Enum-Klasse in Java erweitern, und jeder Enum-Wert ist wie eine statische endgültige öffentliche Instanzimplementierung der Enum-Klasse. Schauen Sie sich die generierten Klassen an und für eine Aufzählung "Foo" mit 10 Werten sehen Sie die generierten Klassen "Foo $ 1" bis "Foo $ 10".
Ich kenne C # jedoch nicht, ich kann nur spekulieren, dass eine Aufzählung in dieser Sprache eher einer traditionellen Aufzählung in Sprachen im C-Stil ähnelt. Ich sehe aus einer schnellen Google-Suche, dass sie jedoch mehrere Werte enthalten können, sodass sie wahrscheinlich auf ähnliche Weise implementiert werden, jedoch mit weitaus mehr Einschränkungen, als der Java-Compiler zulässt.
quelle
Java-Enums ermöglichen einfache typsichere Konvertierungen aus dem Namen mithilfe der vom Compiler generierten valueOf-Methode, d. H.
Das Äquivalent für eine rohe Aufzählung in C # ist ausführlicher:
Wenn Sie jedoch den von Kent empfohlenen Weg gehen, können Sie problemlos eine
ValueOf
Methode in Ihrer Enum-Klasse implementieren .quelle
Ich vermute, dass Enums in C # nur Konstanten innerhalb der CLR sind, aber nicht so vertraut mit ihnen. Ich habe einige Klassen in Java dekompiliert und kann Ihnen sagen, dass Enums einmal konvertiert werden sollen.
Java macht etwas hinterhältiges. Es behandelt die Aufzählungsklasse als eine normale Klasse, wobei, so nah ich es mir vorstellen kann, viele Makros verwendet werden, wenn auf die Aufzählungswerte verwiesen wird. Wenn Sie eine case-Anweisung in einer Java-Klasse haben, die Aufzählungen verwendet, werden die Aufzählungsreferenzen durch Ganzzahlen ersetzt. Wenn Sie zur Zeichenfolge wechseln müssen, wird ein Array von Zeichenfolgen erstellt, die durch eine Ordnungszahl indiziert sind, die in jeder Klasse verwendet wird. Ich vermute, beim Boxen zu sparen.
Wenn Sie diesen Dekompiler herunterladen, werden Sie sehen, wie er seine Klasse erstellt und integriert. Eher faszinierend um ehrlich zu sein. Früher habe ich die Enum-Klasse nicht verwendet, weil ich dachte, sie sei nur für eine Reihe von Konstanten aufgebläht. Mir gefällt es besser als die eingeschränkte Möglichkeit, sie in C # zu verwenden.
http://members.fortunecity.com/neshkov/dj.html - Java-Dekompiler
quelle
Die Aufzählung in Java ist viel komplexer als die C # -Aufzählung und daher leistungsfähiger. Da es sich nur um einen weiteren syntaktischen Zucker zur Kompilierungszeit handelt, frage ich mich, ob es sich wirklich gelohnt hat, die Sprache aufzunehmen, da sie in realen Anwendungen nur begrenzt verwendet wird. Manchmal ist es schwieriger, Dinge aus der Sprache herauszuhalten, als den Druck aufzugeben, ein kleines Feature aufzunehmen.
quelle
quelle
Sie können auch eine Dienstprogrammklasse für jeden Aufzählungstyp verwenden, die eine Instanz mit erweiterten Daten für jeden Aufzählungswert enthält.
quelle