Domanda

Esistono buone soluzioni per rappresentare un'enumerazione parametrizzata in C# 3.0?Sto cercando qualcosa del genere OCaml O Hax ha.Per ora posso solo pensare alla gerarchia delle classi con un semplice campo enum per un facile cambio, forse ci sono idee migliori?

Vedi l'esempio Ocaml di seguito in una delle risposte, segue un codice Haxe:

enum Tree {
   Node(left: Tree, right: Tree);
   Leaf(val: Int);
}
È stato utile?

Soluzione

Non avendo familiarità con OCaml o Haxe, e non essendo abbastanza intelligente da comprendere le altre spiegazioni, sono andato a cercare il Documentazione sull'enumerazione Haxe - il bit "Parametri tipo enum" in basso sembra essere la parte rilevante.

La mia comprensione basata su ciò è la seguente:

Un'enumerazione "normale" è fondamentalmente un valore limitato alle cose che hai definito nella definizione dell'enumerazione.Esempio C#:

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

c può essere Red, Green, Yellow, O Blue, ma nient'altro.

In Haxe, puoi aggiungere tipi complessi alle enumerazioni, esempio inventato dalla loro pagina:

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

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

Che cosa? appare significare è questo c è limitato a essere il valore letterale empty (come le nostre enumerazioni C# vecchio stile), oppure può anche essere un tipo complesso cons(item, next), Dove item è un T E next è un Cell<T>.

Non avendolo mai usato, sembra che probabilmente stia generando alcuni tipi anonimi (come fa il compilatore C# quando lo fai new { Name='Joe'}.
Ogni volta che "accedi" al valore enum, devi dichiarare item E next quando lo fai, e sembra che siano legati a variabili locali temporanee.

Esempio Haxe: puoi vedere 'next' utilizzato come variabile locale temporanea per estrarre i dati dalla struttura contro anonima:

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

Ad essere onesti, questo mi ha lasciato a bocca aperta quando ho "cliccato" su ciò che sembrava stesse facendo.Sembra incredibilmente potente e capisco perché dovresti cercare una funzionalità simile in C#.

Le enumerazioni C# sono più o meno le stesse delle enumerazioni C/++ da cui sono state originariamente copiate.Fondamentalmente è un bel modo di dire #define Red 1 in questo modo il compilatore può eseguire confronti e archiviare numeri interi anziché stringhe durante il passaggio Color oggetti intorno.

Il mio tentativo di farlo in C# sarebbe quello di utilizzare generici e interfacce.Qualcosa come questo:

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 */; }
}

Allora potresti avere un List<ICell<T>> che conterrebbe elementi e cella successiva e potresti inserirli EmptyCell alla fine (o semplicemente avere il Next riferimento esplicitamente impostato su null).I vantaggi sarebbero questo perché EmptyCell non contiene variabili membro, non richiederebbe alcuno spazio di archiviazione (come il empty in Haxe), mentre a Cons la cella sarebbe.
Il compilatore può anche incorporare/ottimizzare i metodi in EmptyCell poiché non fanno nulla, quindi potrebbe esserci un aumento di velocità rispetto al semplice avere a Cons con i dati del membro impostati su null.

Non lo so davvero.Accoglierei con favore qualsiasi altra possibile soluzione poiché non sono particolarmente orgoglioso della mia :-)

Altri suggerimenti

Usare un classe quello con proprietà statiche per rappresentare i valori di enumerazione.Facoltativamente, è possibile utilizzare un costruttore privato per forzare tutti i riferimenti alla classe a passare attraverso una proprietà statica.

Dai un'occhiata a System.Drawing.Color classe.Utilizza questo approccio.

C# (il framework .NET in generale, per quanto ne so) non supporta enumerazioni parametrizzate come fa Java.Detto questo, potresti voler guardare gli Attributi.Alcune delle funzionalità di cui sono capaci le enumerazioni Java sono in qualche modo realizzabili tramite Attributi.

Cosa c'è di sbagliato nell'usare semplicemente una classe per questo?È brutto, ma è così che hanno fatto gli utenti Java finché non hanno avuto il supporto Enum integrato nel linguaggio!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top