抽象基本クラスと派生クラスがあります。それらをBase
と呼びましょうDerived
。
Base
コンストラクターがあります:
public Base(int number)
{
// do something with number
}
そして、Derived
クラスには常にコンストラクターがあります(これはインターフェースを介して保証することはできませんが、それでも私のプログラムではそうです):
public Derived(int number) : base(number)
{
// do some other stuff
}
ここで、から派生したオブジェクトを作成するファクトリメソッドが必要ですBase
。これは次のように呼び出す必要があります。
Base.Create<Derived>(someNumber);
しかし、私はこのメソッドを正しい方法で実装する方法を知りません。最もエレガントな解決策は、次のようなことを行うことだと思います。
public static T Create<T>(int number) where T : Base, new(int)
{
return new T(number);
}
しかし、C#はパラメーター化されたコンストラクター制約をサポートしておらず、パラメーターのないもの new(int)
のみをサポートしているようです。この解決策は非常に明確であり、私が望むものを正確に表現しています。しかたがない..
代わりに、基本的にtypeパラメーターをオンにして、次のように正しい型のインスタンスを作成し、インスタンス化することができます。
public static Base Create<T>(int number) where T : Base, new(int)
{
if (typeof(T) == typeof(Derived))
{
return new Derived(number);
}
// and so on for all other derived types
}
しかし、これには、新しい派生クラスを作成するたびにメソッドを更新する必要があります。これは残念なことです。その上、typeof(T) == typeof(Derived)
あまりにもハックっぽいようです。また、このアプローチでは、ファクトリメソッドの戻り値の型をのBase
代わりに使用する必要があるようですがT
、これも残念です。その場合、型パラメーターの代わりに列挙型を使用することも簡単にできます。
私が望むことを達成するためのより良い方法があるのだろうか?
アクティベーターを使用してインスタンスを作成できます。
public static T Create<T>(int number) where T : Base
{
return (T) Activator.CreateInstance(typeof (T), number);
}
この場合、新しい派生クラスを作成するときにメソッドを更新する必要はありません。これは、単一の整数パラメーターを受け取るコンストラクターが常にあることを前提としています。そのようなコンストラクターが存在しない場合、実行時例外が発生します。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加