Foo<T>
クラスBar<U>
とBat<T>
派生
元の汎用基本クラスがあります。U
から派生しT
ます。U
Bat と Bar は同様の実装ですが、タイプの値を異なる方法で処理する必要があるいくつかの場所のみが異なります。
には、型の引数を取り、またはオブジェクトを作成Foo
するファクトリ メソッドがあります。おおよそ次のようになります。Create
T
Bar
Bat
public static IFoo<T> Create(T input) {
if (input.TypeIdentifier == Types.Bar) {// exemplary type check
// input is of or derives from `U`
// return a Bar<U>
} else
return new Bat(input);
}
// usage:
U myU = new ClassThatDerivesFromU();
T myT = new ClassThatDerivesFromT(CouldBe.Of(Type.U));
var myFoo1 = Create(myU); // of type IFoo<U>
var myFoo2 = Create(myT); // of type IFoo<T>
T
は ではないため、オブジェクトU
をインスタンス化できません。Bar
考えられる解決策の1つは次のとおりです。
public static U To<T, U>(T input) where U : T {
return input as U;
}
// to create Bar:
new Bar(To<T, U>(input));
ただし、これは非常にハックであり、構造体では使用できません (この場合、継承のためにとにかく構造体にすることはできませんが、たとえばaまたは aにU
応じてメソッドを呼び出したい別のケースがあります)。T
struct
class
C++ では、このようなシナリオは、メソッドの複数のオーバーロードに異なる型制約を指定することで解決できます (iirc) Create
。コンパイラは型をチェックしT
、適切なメソッドを選択します (U
またはT
型制約として)。
C# に同様の組み込みソリューションがあることは知りませんが、代わりに使用できる洗練された回避策があるのではないでしょうか? (反射は明白な答えですが、オプションではありません)