C#ジェネリックの「デフォルト」タイプのパラメータへの合理的なアプローチはありますか?
-
22-08-2019 - |
質問
C ++のテンプレートでは、1は、特定のタイプのパラメータがデフォルトであることを指定することができます。即ち明示的に指定しない限り、それは型Tを使用します。
このC#で行わまたは近似することができますか?
私のようなものを探しています:
public class MyTemplate<T1, T2=string> {}
だから、明示的にT2
を指定していないタイプのインスタンス:
MyTemplate<int> t = new MyTemplate<int>();
基本的に次のようになります。
MyTemplate<int, string> t = new MyTemplate<int, string>();
最終的にはかなり広く使用されているテンプレートがであることを特徴とする請求私はケースで探していますが、私は追加の型パラメータで拡大を検討しています。私は私が推測する、サブクラス化することもできますが、この調子で他のオプションがあった場合、私は興味がありました。
解決
サブクラスは最適なオプションです。
私はあなたの主なジェネリッククラスをサブクラス化します
class BaseGeneric<T,U>
特定のクラスと
class MyGeneric<T> : BaseGeneric<T, string>
これは、1つの場所(基底クラス)で、あなたのロジックを維持することを容易にするだけでなく、両方の使用オプションを提供しやすいです。クラスによっては、これを実現するために必要な、おそらく非常に少し余分な作業があります。
他のヒント
一つの解決策は、サブクラス化されます。私が代わりに使用するもう一つは、(varキーワードと組み合わせて)ファクトリメソッドです。
public class MyTemplate<T1,T2>
{
public MyTemplate(..args..) { ... } // constructor
}
public static class MyTemplate{
public static MyTemplate<T1,T2> Create<T1,T2>(..args..)
{
return new MyTemplate<T1, T2>(... params ...);
}
public static MyTemplate<T1, string> Create<T1>(...args...)
{
return new MyTemplate<T1, string>(... params ...);
}
}
var val1 = MyTemplate.Create<int,decimal>();
var val2 = MyTemplate.Create<int>();
上記の例でval2
はそれから派生した型のとしないの型MyTemplate<int,string>
である。
型class MyStringTemplate<T>:MyTemplate<T,string>
はMyTemplate<T,string>
と同じタイプではありません。
これは、特定のシナリオでいくつかの問題を引き起こす可能性があります。
たとえば、あなたがMyTemplate<T,string>
にMyStringTemplate<T>
のインスタンスをキャストすることはできません。
あなたもそうのようなクラスのオーバーロードを作成することができます。
public class MyTemplate<T1, T2> {
public T1 Prop1 { get; set; }
public T2 Prop2 { get; set; }
}
public class MyTemplate<T1> : MyTemplate<T1, string>{}
C#は、このような機能をサポートしていません。
あなたが言ったように、、あなたは(それが密閉されていない場合は、すべてのコンストラクタの宣言を複製)、それをサブクラスが、それは完全に別物だことができます。
残念ながら、C#が何をしようとするサポートしていません。これは、パラメータのデフォルトタイプは、一般的な制約を遵守しなければならないとCLRは型の安全性を確保しようとしたときに最も可能性の頭痛を作成することを指定した実装が困難な特徴になります。