この状況では:
// We have an interface...
interface InterfaceB {}
// And this class implements the interface.
class ImplementsB : InterfaceB {}
// But this class does not.
class DoesNotImplementB {}
次のように定義できますMethodA。
static Type MethodA<TClass, TInterface>()
where TClass : TInterface
{
return typeof(TClass);
}
次に、以下が機能します。
Type t = MethodA<ImplementsB, InterfaceB>();
ただし、これによりコンパイル時エラーが発生します。
Type t = MethodA<DoesNotImplementB, InterfaceB>();
タイプ'DoesNotImplementB'は、ジェネリック型またはメソッド'MethodA <TClass、TInterface>()'のタイプパラメーター'TClass'として使用できません。'DoesNotImplementB'から'InterfaceB'への暗黙の参照変換はありません。
したがって、このようにして、の結果がを実装するクラスの結果でMethodAあることが確実になります。そのオブジェクトが与えられると、後で次のようにインスタンス化できます。TypeTInterfaceType
public object Instantiate(Type type)
{
// Call the default constructor.
// You can change this to call any constructor you want.
var constructor = type.GetConstructor(Type.EmptyTypes);
var instance = constructor.Invoke(new object[0]);
return instance;
}
Typeが何らかのインターフェイスと互換性があることがわかっている場合はTInterface、次のような追加のメソッドを使用してキャストを回避できます。
public TInterface Instantiate<TInterface>(Type type)
{
return (TInterface)Instantiate(type);
}
ただし、が何らかの形で実装されていない場合typeは、実行時に取得します。コンパイル時に特定のインターフェイスを実装する型になるように制約する方法はありません。ただし、実行時に、例外を回避するためにチェックすることができます。TypeTInterfaceInvalidCastExceptionTypeInvalidCastException
public TInterface Instantiate<TInterface>(Type type)
{
if (!typeof(TInterface).IsAssignableFrom(type))
throw new Exception("Wrong type!");
return (TInterface)Instantiate(type);
}
typeof(TType)これはオブジェクトを生成する式であることに注意してください。そのTypeため、どこにtypeof()いてもそれを任意の変数に置き換えることができType、その逆も可能です。
これはあなたが知りたかったことですか?