如何通过反射获取通用参数名称

时间:2017-03-31 14:12:06

标签: c# generics reflection

给出通用类

class Foo<TData> { }

和具体类型

var type = typeof(Foo<string>) //Fpp`[System.String]
var genericType = type.GetGenericTypeDefinition(); //Foo`1[TData]

我想得到“TData”。或者另一种方式:根据通用参数名称获取泛型参数的值:

GetGenericArgumentType(typeof(Foo<string>), "TData") //should return System.String

2 个答案:

答案 0 :(得分:1)

好的,基于这篇文章:https://msdn.microsoft.com/en-us/library/system.type.getgenericparameterconstraints(v=vs.110).aspx

Type def = typeof(Foo<>);
Type[] defparams = def.GetGenericArguments();
Console.WriteLine(defParams[0].Name); // writes "TData"
Console.WriteLine(defParams[0].GenericParameterPosition); // writes 0

Type concreteDef = typeof(Foo<string>)
Type[] concreteDefParams = concreteDef.GetGenericArguments();
Console.WriteLine(concreteDefParams[0].FullName); // writes "System.String"

答案 1 :(得分:0)

以下内容是可行的:(这仅用于演示,它假定类型是通用的,参数名称确实存在)

public string GetGenericArgumentType(Type type, string paramName)
{

    var genericType = type.GetGenericTypeDefinition(); 

    var genericParam = genericType
        .GetGenericArguments()
        .Select((t, i) => new { Index = i, t.Name })
        .First(arg => arg.Name == paramName);

    return type.GetGenericArguments()[genericParam.Index].Name;
}

class GenericFoo<TData, TSecondData> { }

public void GetGenericArgumentTypeTest()
{
    string name1 = this.GetGenericArgumentType(
                        typeof(GenericFoo<string, int>), "TData"); //String
    string name2 = this.GetGenericArgumentType(
                        typeof(GenericFoo<string, int>), "TSecondData"); //Int32
}