以下の例のような列挙型の基本クラスがあります。私の実際の実装は、明示的および暗黙的なキャスト、リフレクション、フラグ、例外処理など、はるかに多くをカバーしていますが、基本的には次のとおりです。
public abstract class Enumeration<T> {
// enum value
protected readonly T _value;
// collection of all values
private static readonly HashSet<Enumeration<T>> _values
= new HashSet<Enumeration<T>>();
public T Value {
get { return _value; }
}
// returns all values
public static IEnumerable<Enumeration<T>> GetValues() {
return _values.AsEnumerable();
}
}
さて、特定の型 (文字列、整数など) の列挙が必要なときはいつでも、次のように宣言できます。
public sealed class MyEnum : Enumeration<string> {
public static readonly MyEnum EnumVal1 = new MyEnum("Val1!");
public static readonly MyEnum EnumVal2 = new MyEnum("Val2!");
public static readonly MyEnum EnumVal3 = new MyEnum("Val3!");
}
そして、プライベートまたはパブリック コンストラクターを使用して、拡張可能にするかどうかを指定します。
public MyEnum(string enumVal) : base(value: enumVal) {}
値をベース ctor に渡します。
protected Enumeration(T value) {
_value = value;
_values.Add(this);
}
これは、string、int、double などの型では問題なく機能します。しかし、複雑なオブジェクトを列挙したい場合はどうすればよいでしょうか?
public sealed class ComplexObj: Enumeration<ComplexObj> {
public static readonly ComplexObj Val1 = new ComplexObj("val1", 455, null);
}
インスタンス化されたオブジェクトを基本コンストラクターに渡すことができないため、ここで問題が発生します。
public ComplexObj(string name, int someval, string another)
: base(this) {} // doesn't work
そして、新しいオブジェクトをコンストラクターに渡すと、..ご存知のとおり:)
: base(new ComplexObj(name, someval, another)) {} // lol
どうすればこの問題を解決できますか? オブジェクト自体を基本コンストラクターに渡す方法はありますか?