C#で子クラスのTypeから継承元インタフェースのジェネリック引数を得る方法
外部で定義された型のインスタンスに対してアレコレするフレームワークを作っている時、 ジェネリクスで指定された型が知りたくなる時がある。
言語はC#。
"How to detect Type of generic property, in other words generic argument, from derived class"
https://gist.github.com/kazyx/9cdc033dd3bf19724b5253c759705a8f
わかりやすく言うと、typeof(MyFoo) から typeof(Foo) を得たい。
インタフェースがジェネリック引数型のプロパティやフィールドを定義している場合、それをリフレクションで引いてくれば型情報が得られる。
それより前だと GetProperty("MyParameter") とする必要があり微妙。
ジェネリック引数を含んだの継承元インタフェース型をリフレクションで得ることができるので、そこからジェネリック引数として取得する。
ちなみに、typeof(MyInterface<>).FullName は "MyInterface`1" らしい。
https://msdn.microsoft.com/ja-jp/library/ayfa0fcd(v=vs.110).aspx
おわり。
言語はC#。
"How to detect Type of generic property, in other words generic argument, from derived class"
https://gist.github.com/kazyx/9cdc033dd3bf19724b5253c759705a8f
わかりやすく言うと、typeof(MyFoo) から typeof(Foo) を得たい。
public interface MyInterface<T> {
T MyParameter { set; get; }
}
public class Foo {
public string Bar { set; get; }
}
public class MyFoo : MyInterface<Foo> {
public Foo MyParameter { set; get; }
}
1. プロパティ名やフィールド名から辿る
インタフェースがジェネリック引数型のプロパティやフィールドを定義している場合、それをリフレクションで引いてくれば型情報が得られる。
public Type GetTypeOfGenericArgByPropertyName(Type derivedClassType) {
var myParamPropertyInfo = derivedClassType.GetProperty(nameof(MyInterface.MyParameter));
// If derivedClassType is 'MyFoo', myParamPropertyInfo is PropertyInfo of MyFoo.MyParameter
return myParamPropertyInfo.PropertyType;
}
C#6 以降のモダンな環境であれば nameof が使えるのでこれでもまあ良いかもしれない。それより前だと GetProperty("MyParameter") とする必要があり微妙。
2. ジェネリックインタフェースの型情報から辿る
ジェネリック引数を含んだの継承元インタフェース型をリフレクションで得ることができるので、そこからジェネリック引数として取得する。
public Type GetTypeOfGenericArg(Type derivedClassType) {
var typedMyInterfaceType = derivedClassType.GetInterface(typeof(MyInterface<>).FullName);
// If derivedClassType is 'MyFoo', typedMyInterfaceType is typeof(MyInterface)
return typedMyInterfaceType.GetGenericArguments()[0];
}
こっちの方法であれば、Unity とかの古い C# 環境でも使える。 ちなみに、typeof(MyInterface<>).FullName は "MyInterface`1" らしい。
https://msdn.microsoft.com/ja-jp/library/ayfa0fcd(v=vs.110).aspx
For generic interfaces, the name parameter is the mangled name, ending with a grave accent (`) and the number of type parameters. This is true for both generic interface definitions and constructed generic interfaces. For example, to find IExample<T> (IExample(Of T) in Visual Basic) or IExample<string> (IExample(Of String) in Visual Basic), search for "IExample`1".
おわり。
コメント
コメントを投稿