C# 如何通过反射获取泛型参数名

C# 如何通过反射获取泛型参数名,c#,generics,reflection,C#,Generics,Reflection,给定泛型类 class Foo<TData> { } class Foo{} 和混凝土类型 var type = typeof(Foo<string>) //Fpp`[System.String] var genericType = type.GetGenericTypeDefinition(); //Foo`1[TData] var type=typeof(Foo)//Fpp`[System.String] var genericType=type.GetGene

给定泛型类

class Foo<TData> { }
class Foo{}
和混凝土类型

var type = typeof(Foo<string>) //Fpp`[System.String]
var genericType = type.GetGenericTypeDefinition(); //Foo`1[TData]
var type=typeof(Foo)//Fpp`[System.String]
var genericType=type.GetGenericTypeDefinition()//Foo`1[TData]
我想得到“TData”。或者另一种方法:基于泛型参数名称获取泛型参数的值:

GetGenericArgumentType(typeof(Foo<string>), "TData") //should return System.String
GetGenericArgumentType(typeof(Foo),“TData”)//应返回System.String

好的,根据本文:

Type def=typeof(Foo);
类型[]defparams=def.GetGenericArguments();
Console.WriteLine(defParams[0].Name);//写入“TData”
Console.WriteLine(defParams[0].GenericParameterPosition);//写入0
类型concreteDef=typeof(Foo)
类型[]concreteDefParams=concreteDef.GetGenericArguments();
Console.WriteLine(concreteDefParams[0].FullName);//写入“System.String”

这在以下方面是可行的:(这只是为了演示,它假设类型是泛型的,并且参数名确实存在)

公共字符串GetGenericArgumentType(类型类型,字符串参数名)
{
var genericType=type.GetGenericTypeDefinition();
var genericParam=genericType
.GetGenericArguments()的
.Select((t,i)=>new{Index=i,t.Name})
.First(arg=>arg.Name==paramName);
返回类型.GetGenericArguments()[genericParam.Index].Name;
}
类GenericFoo{}
public void GetGenericArgumentTypeTest()
{
字符串名称1=this.GetGenericArgumentType(
typeof(GenericFoo),“TData”);//字符串
字符串名称2=this.GetGenericArgumentType(
typeof(GenericFoo),“TSecondData”);//Int32
}

如果它只有一个参数。类型.GetGenericArguments()[0]。FullName返回System.String而不是TData
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"
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
}