C#Reflectionピックアップ

4798 ワード

1.ネストされた汎用タイプまたはメソッドのインスタンス化:
class GenericClass<T>
{
    public class NestedGenericClass<T2>
    {
        ...
    }
    public void GenericMethod<T2>(T2 t)
    {
        ...
    }
}

上記のNestedGenericClass<>およびGenericMethod<>をReflectionでインスタンス化するには、それらの包含クラス、すなわちGenericClass<>に配慮する必要があります.
通常、genNestedClsタイプ変数には、次の手順でインスタンス化が完了します.
Type gcls = typeof("GenericClass<>");
Type genGcls = gc.MakeGenericClass(typeof(int));
Type nestedCls = genGc.GetNestedType("NestedGenericClass`1");
Type genNestedCls = nestedCls.MakeGenericClass(typeof(double));

しかし、実際には、実行時に最後の文を実行すると、汎用パラメータの不一致エラーが報告されます.正しい方法は、次のとおりです.
Type genNestedCls = nestedCls.MakeGenericClass(typeof(int), typeof(double));

クラスを含む汎用パラメータも代入されますが、実際には、汎用パラメータがインスタンス化された組み込みクラスを使用せずに内部ネストされたクラスを構築することもできます.
Type gcls = typeof("GenericClass<>");
Type nestedCls = gcls.GetNestedType("NestedGenericClass`1");

同様に、
Type nestedCls = typeof(GenericClass<>.NestedGenericClass<>);

これらの構築によって形成される最後のgenNestedClassのタイプ値はすべて一致し、typeof(GenericClass.NestedGenericClass)と完全に等しい.
しかし、これらは内蔵汎用法には適用されず、この方法を実例化するには以下の直感的な方法が採用されている.
Type gcls = typeof("GenericClass<>");
Type genGcls = gc.MakeGenericClass(typeof(int));
Type m = genGcls.GetMethod("GenericMethod");
Type gm = m.MakeGenericMethod(typeof(double")); 

これで形成するgmはGenericClassに相当する.GenericMethod(double)
2.次の例のコードは、汎用反射の一部をカバーしています.
class ParClass<T, T2>
{
}

class GenClass<T>
{
    public void Method<T2>(ParClass<T, T2> pars)
    {
    }
}

static void Main(string[] args)
{
    Type genClassUnassigned = typeof(GenClass<>);
    Type genClassAssigned = genClassUnassigned.MakeGenericType(typeof(int));
    MethodInfo[] misClassUnassigned = genClassUnassigned.GetMethods();
    MethodInfo[] misClassAssigned = genClassAssigned.GetMethods();

    MethodInfo miClassUnassigned = misClassUnassigned[0];
    MethodInfo miClassAssigned = misClassAssigned[0];
    MethodInfo miClassMethodAssigned = miClassAssigned.MakeGenericMethod(typeof(double));
    
    bool isGMClassUnassigned = miClassUnassigned.IsGenericMethod;  // true
    bool isGMClassAssigned = miClassAssigned.IsGenericMethod;  // true
    bool isGMClassMethodAssigned = miClassMethodAssigned.IsGenericMethod;  // true

    bool containsGPClassUnassigned = miClassUnassigned.ContainsGenericParameters;  // true
    bool containsGPClassAssigned = miClassAssigned.ContainsGenericParameters;  // true
    bool containsGPClassMethodAssigned = miClassMethodAssigned.ContainsGenericParameters;  // false

    Type[] typeGenArgsClassUnassigned = miClassUnassigned.GetGenericArguments();
    Type[] typeGenArgsClassAssigned = miClassAssigned.GetGenericArguments();
    Type[] typeGenArgsClassMethodAssigned = miClassMethodAssigned.GetGenericArguments();

    ParameterInfo[] parsClassUnassigned = miClassUnassigned.GetParameters();
    ParameterInfo[] parsClassAssigned = miClassAssigned.GetParameters();
    ParameterInfo[] parsClassMethodAssigned = miClassMethodAssigned.GetParameters();

    Type[] ptsClassUnassigned = new Type[parsClassUnassigned.Length];
    Type[] ptsClassAssigned = new Type[parsClassAssigned.Length];
    Type[] ptsClassMethodAssigned = new Type[parsClassMethodAssigned.Length];
    for (int i = 0; i < ptsClassUnassigned.Length; i++)
	ptsClassUnassigned[i] = parsClassUnassigned[i].ParameterType;
    for (int i = 0; i < ptsClassUnassigned.Length; i++)
	ptsClassAssigned[i] = parsClassAssigned[i].ParameterType;
    for (int i = 0; i < ptsClassUnassigned.Length; i++)
	ptsClassMethodAssigned[i] = parsClassMethodAssigned[i].ParameterType;

    Type t1 = typeof(ParClass<,>);
    Type tt1 = ptsClassUnassigned[0];
    
    Type[] gaT1 = t1.GetGenericArguments();
    Type[] gaTt1 = tt1.GetGenericArguments();
    Type gtT1 = t1.GetGenericTypeDefinition();
    Type gtTt1 = tt1.GetGenericTypeDefinition();
    bool eq1 = gtT1 == gtTt1;  // true
    Type t3 = t1.MakeGenericType(typeof(int), typeof(double));
    bool eq3 = ptsClassMethodAssigned[0] == t3;  // true
    bool eq13 = t3.GetGenericTypeDefinition() == gtT1;  // true

    Type tt2 = ptsClassAssigned[0];
    Type[] gaTt2 = tt2.GetGenericArguments();
    bool tt2IsG = tt2.IsGenericParameter;  // false
    bool gaTt20IsG = gaTt2[0].IsGenericParameter;  // false
    bool gaTt21IsG = gaTt2[1].IsGenericParameter;  // true
}

(未完待機)