答えはノーだと思いますが、次のようなことが可能かどうか知りたいです:
public class MyGenericClass<TSomeClass> {
public void MyGenericMethod<TSomeInterface>()
// This doesn't compile.
where TSomeClass : TSomeInterface
{
//...
}
}
TSomeInterface
上記の (動作しない) 例で示していることは、任意の基本クラス、実装されたインターフェイス、または (本当に凝りたい場合) の暗黙的な変換になるように制約することですMyGenericClass
。
注:
これが C# で実装されなかった理由は、一般的な制約が実際にはコード コントラクトを意図したものではないためだと思われます。これが、ここで使用しようとしている方法です。TSomeInterface
によって実装されている限り、タイプが何であるかは本当に気にしませんTSomeClass
。
これまでのところ、私はこれを一緒にハッキングしました:
public class MyGenericClass<TSomeClass> {
public void MyGenericMethod<TIntermediateType, TSomeInterface>()
where TIntermediateType : TSomeClass, TSomeInterface
{
//...
}
}
これは、多かれ少なかれ、私が望む制約を強制します (それTSomeClass
は、から継承する必要があるか、インターフェイスの場合は、実装する必要がありTSomeInterface
ますTIntermediateType
) 。 TSomeClass
):
var myGenericInstance = new MyGenericClass<TSomeClass>();
myGenericInstance.MyGenericMethod(TSomeClass, TSomeInterface);
さらに、上記のハックは、呼び出し元が理論上TSomeClass
、最初の型パラメーターとして のサブクラスを指定でき、サブクラスのみが を実装する可能性があるため、壊れていますTSomeInterface
。
私がこれをしたい理由は、WCF サービスの流暢なファクトリ パターンを作成していて、(コンパイル時に) 呼び出し元がサービス クラスが作成しないコントラクトでエンドポイントを作成しようとするのを防ぎたいからです。実装しないでください。私は明らかに実行時にこれをチェックできます (実際には WCF がこれを行ってくれます) が、私はコンパイル時のチェックの大ファンです。
私がここにいるものを達成するためのより良い/よりエレガントな方法はありますか?