Frage

Gibt es gute Lösungen eine parametrisierte Enum in C# 3.0 zu vertreten? Ich bin auf der Suche nach so etwas wie OCaml oder Haxe hat. Ich kann nur mit einem einfachen Enum Feld für die einfachen Wechsel jetzt die Klassenhierarchie denkt, vielleicht gibt es bessere Ideen?

Siehe Ocaml Beispiel unten in eine der Antworten, ein Haxe Code folgt:

enum Tree {
   Node(left: Tree, right: Tree);
   Leaf(val: Int);
}
War es hilfreich?

Lösung

Nicht mit OCaml oder Haxe vertraut zu sein, und nicht klug genug, um die anderen Erklärungen zu verstehen, ging ich und sah den Haxe Enum Dokumentation -. die 'Enum Typ Parameter' Bit am Boden scheint der relevante Teil zu sein

Ihr Verständnis auf dieser Grundlage lautet wie folgt:

Ein ‚normaler‘ Enum ist im Grunde ein Wert, der auf die Dinge beschränkt, die Sie in Ihrer Enumerationsdefinition definiert haben. C # Beispiel:

enum Color{ Red, Green, Yellow, Blue };
Color c = Color.Red;

c kann entweder Red, Green, Yellow oder Blue werden, aber sonst nichts.

In Haxe können Sie komplexe Typen Aufzählungen, konstruiertes Beispiel von ihrer Seite hinzufügen:

enum Cell<T>{ 
  empty; 
  cons( item : T, next : Cell<T> )
}

Cell<int> c = <I don't know>;

Was erscheint zu verstehen ist, dass c beschränkt ist entweder der wörtliche Wert empty (wie unsere altmodischen C # Aufzählungen) sein, oder es kann auch ein komplexer Typ cons(item, next) sein, wo item a T und next ist ein Cell<T>.

Nicht immer dies sieht es benutzt zu haben, wie es wahrscheinlich ist, einige anonyme Typen zu erzeugen (wie, wie der C # Compiler tut, wenn Sie new { Name='Joe'} tun.
Jedes Mal, wenn Sie ‚Zugang‘ der ENUM-Wert, haben Sie item und next zu erklären, wenn Sie dies tun, und es sieht aus wie sie auf temporäre lokale Variablen gebunden bekommen.

Haxe Beispiel - Sie können sehen, ‚next‘ als temporären lokalen Variable verwendet wird, um Daten aus der anonymen cons Struktur zu ziehen:

switch( c ) {
  case empty : 0;
  case cons(item,next): 1 + cell_length(next);
}

Um ehrlich zu sein, das hat mich sehr beeindruckt, als ich ‚geklickt‘ auf, was es schien dabei zu sein. Es scheint unglaublich mächtig, und ich kann sehen, warum sie eine ähnliche Funktion in C # suchen würde.

C # Aufzählungen sind so ziemlich das gleiche wie C / ++ Aufzählungen, aus denen sie ursprünglich kopiert wurden. Es ist im Grunde eine nette Art #define Red 1 zu sagen, so kann der Compiler anstelle von Strings mit ganzen Zahlen Vergleiche und Speicher tun, wenn Sie Color sind vorbei Objekte um.

Mein Stich an diese in C # zu tun wäre Generika und Schnittstellen zu verwenden. So etwas wie folgt aus:

public interface ICell<T> {
   T Item{ get; set; }
   ICell<T>{ get; set; }
}

class Cons<T> : ICell<T> {
  public T Item{ get; set; } /* C#3 auto-backed property */
  public Cell<T> Next{ get; set; }
}

class EmptyCell<T> : ICell<T>{
  public T Item{ get{ return default(T); set{ /* do nothing */ }; }
  public ICell<T> Next{ get{ return null }; set{ /* do nothing */; }
}

Dann könnte man ein List<ICell<T>> hat, welche Elemente und nächste Zelle enthalten würde, und man kann EmptyCell am Ende ein (oder einfach nur den Next explizit Bezug auf null gesetzt). Die Vorteile wäre, dass, weil keine EmptyCell Elementvariablen enthält, ist es kein Speicherplatz (wie die in empty Haxe) erfordern würde, wohingegen eine Cons Zelle würde.
Der Compiler kann inline / auch die Methoden in EmptyCell optimiert, wie sie nichts tun, so gibt es eine Geschwindigkeitserhöhung kann über nur eine Cons mit mit ihm ist gesetzt Mitgliedsdaten auf Null.

Ich weiß es nicht wirklich. Ich würde begrüßen alle anderen möglichen Lösungen, wie ich bin nicht besonders stolz auf meine ein: -)

Andere Tipps

Verwenden Sie ein Klasse , die mit statischen Eigenschaften der Aufzählungswert darzustellen. Sie können optional einen privaten Konstruktor verwenden, um alle Verweise auf die Klasse zu zwingen, durch eine statische Eigenschaft zu gehen.

Werfen Sie einen Blick auf die System.Drawing.Color Klasse. Es nutzt diesen Ansatz.

C # (.NET Framework im Allgemeinen, soweit ich weiß) nicht unterstützt parametrisierte Aufzählungen wie Java tut. Dass gesagt wird, könnte man auf Attribute suchen. Einige der Features, die Java Aufzählungen der Lage sind, etwas machbar durch Attribute.

Was ist los mit nur einer Klasse für diese Verwendung? Sein hässlich, aber das ist, wie die Java Leute es taten, bis sie integrierte Sprach Enum Unterstützung hatte!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top