パラメータ化された列挙型を表す良い解決策はありますC# 3.0か? OCamlやHaxeのようなものを探しています。今のところ、簡単に切り替えられるように単純な列挙型フィールドを持つクラス階層しか考えられませんが、もっと良いアイデアがあるのではないでしょうか?
以下の返信の 1 つである Ocaml の例を参照してください。Haxe コードは次のとおりです。
enum Tree {
Node(left: Tree, right: Tree);
Leaf(val: Int);
}
OCaml や Haxe に精通しておらず、他の説明を理解するほど頭が良くないので、Haxe enum のドキュメントを調べてみました。一番下の「Enum Type Parameters」ビットが関連部分のようです。
それを踏まえた私の理解は以下の通りです。
「通常の」列挙型は基本的に、列挙型定義で定義したものに制限される値です。C# の例:
enum Color{ Red, Green, Yellow, Blue };
Color c = Color.Red;
cRed、Green、Yellow、またはのいずれかであり、Blueそれ以外は何もありません。
Haxe では、複雑な型を列挙型に追加できます。ページからの不自然な例:
enum Cell<T>{
empty;
cons( item : T, next : Cell<T> )
}
Cell<int> c = <I don't know>;
これが意味しているように見えるのはc、 がリテラル値empty(昔ながらの C# 列挙型のように) に制限されるか、が a であり、 が aである複雑な型cons(item, next)であることもできるということです。itemTnextCell<T>
これを使用したことがないのは、おそらくいくつかの匿名型を生成しているように見えます(C#コンパイラがそうするときのようにnew { Name='Joe'}。
列挙値に「アクセス」するたびに、宣言する必要がitemありnext、そうすると、それらのように見えます一時的なローカル変数にバインドされます。
Haxe の例 - 'next' が一時的なローカル変数として使用され、無名コンス構造からデータを引き出すことがわかります。
switch( c ) {
case empty : 0;
case cons(item,next): 1 + cell_length(next);
}
正直なところ、これが何をしているように見えるかを「クリック」したとき、これは私の心を吹き飛ばしました。信じられないほど強力なようで、C# で同様の機能を探している理由がわかります。
C# 列挙型は、元のコピー元の C/++ 列挙型とほとんど同じです。これは基本的に、オブジェクト#define Red 1を渡すときにコンパイラが文字列ではなく整数を使用して比較および格納できるようにするための良い言い方です。Color
C# でこれを行うための私の刺し傷は、ジェネリックとインターフェイスを使用することです。このようなもの:
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 */; }
}
次にList<ICell<T>>、アイテムと次のセルを含む a を作成EmptyCellし、最後に挿入できます (または、Next参照を明示的に null に設定するだけです)。利点は、メンバー変数が含まれていないため、( HaxeEmptyCellの のような) ストレージ スペースを必要としないことですが、セルには必要です。
コンパイラはメソッドをインライン化/最適化することもできるため、メソッドのメンバー データを null に設定するだけで速度が向上する可能性があります。emptyConsEmptyCellCons
よくわかりません。私は自分の解決策を特に誇りに思っていないので、他の可能な解決策を歓迎します:-)
列挙値を表すために静的プロパティを持つクラスを使用します。オプションで、プライベートコンストラクターを使用して、クラスへのすべての参照が静的プロパティを通過するように強制できます。
System.Drawing.Colorクラスを見てください。このアプローチを使用します。
C# (私が知る限り、.NET フレームワーク全般) は、Java のようにパラメーター化された列挙型をサポートしていません。そうは言っても、属性を見たいと思うかもしれません。Java 列挙型で実行できる機能の一部は、属性を介してある程度実行できます。
これにクラスを使用するだけで何が問題なのですか? それは醜いですが、Java の人々が言語に統合された Enum サポートを得るまでは、それがどのように行われていたかです!