C#使用反射获取通用参数名

C#使用反射获取通用参数名,c#,generics,reflection,C#,Generics,Reflection,假设我有这样一个C#类: class MyClass<Tkey,Tvalue>{} 您还可以使用获取类型。您可以从中选择名称: IEnumerable<string> genericParameterNames = instance.GetType().GetGenericArguments().Select(t => t.Name); IEnumerable genericParameterNames=instance.GetType().GetGeneric

假设我有这样一个C#类:

class MyClass<Tkey,Tvalue>{}
您还可以使用

获取类型。您可以从中选择名称:

IEnumerable<string> genericParameterNames = instance.GetType().GetGenericArguments().Select(t => t.Name);
IEnumerable genericParameterNames=instance.GetType().GetGenericArguments().Select(t=>t.Name);
编辑

要获取泛型参数的名称,您应该查看。简化版本如下:

IEnumerable<string> genericParameterNames = instance.GetType()
    .GetGenericTypeDefinition()
    .GetGenericArguments()
    .Select(t => t.Name)
IEnumerable genericParameterNames=instance.GetType()
.GetGenericTypeDefinition()
.GetGenericArguments()的
.Select(t=>t.Name)

首先必须对类型使用方法
GetGenericTypeDefinition()
,以获取表示泛型模板的另一个类型。然后您可以使用
GetGenericArguments()
来接收原始占位符的定义,包括它们的名称

例如:

    class MyClass<Tkey, Tvalue> { };


    private IEnumerable<string> GetTypeParameterNames(Type fType)
    {
        List<string> result = new List<string>();

        if(fType.IsGenericType)
        {
            var lGenericTypeDefinition = fType.GetGenericTypeDefinition();

            foreach(var lGenericArgument in lGenericTypeDefinition.GetGenericArguments())
            {
                result.Add(lGenericArgument.Name);
            }
        }

        return result;
    }

    private void AnalyseObject(object Object)
    {
        if (Object != null)
        {
            var lTypeParameterNames = GetTypeParameterNames(Object.GetType());
            foreach (var name in lTypeParameterNames)
            {
                textBox1.AppendText(name + Environment.NewLine);
            }
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        var object1 = new MyClass<string, string>();
        AnalyseObject(object1);

        var object2 = new List<string>();
        AnalyseObject(object2);

        AnalyseObject("SomeString");
    }
classmyclass{};
私有IEnumerable GetTypeParameterNames(类型fType)
{
列表结果=新列表();
if(fType.IsGenericType)
{
var lGenericTypeDefinition=fType.GetGenericTypeDefinition();
foreach(lGenericTypeDefinition.GetGenericArguments()中的var lGenericArgument)
{
result.Add(lGenericArgument.Name);
}
}
返回结果;
}
私有void分析对象(对象)
{
if(对象!=null)
{
var lTypeParameterNames=GetTypeParameterNames(Object.GetType());
foreach(lTypeParameterNames中的变量名称)
{
textBox1.AppendText(name+Environment.NewLine);
}
}
}
私有无效按钮1\u单击(对象发送者,事件参数e)
{
var object1=新的MyClass();
分析对象(object1);
var object2=新列表();
分析对象(object2);
AnalyseObject(“SomeString”);
}

这将返回实际使用类型的名称,当然不是模板参数的名称,而是类型名称,例如“Int32”。我需要得到“Tkey”@czubehead哦,我以为这些只是实际姓名的占位符。你试过克里斯托斯的答案吗?@czubehead看一看NineBerry的答案,他很好地解释了如何找到这些名字。我对我的答案进行了编辑,以显示如何在没有开销的情况下获取这些名称。当类型不是泛型时,使用Linq的这个简短表单将引发异常,因为GetGenericTypeDefinition()将返回null。您可能应该添加一个更简单的示例,而不需要所有不必要的开销(您可以复制我的,然后我将删除我的答案);)非常感谢。这正是我所需要的。我将它简化了一点,但使用LINQ:
List genericalarguments=T.GetGenericTypeDefinition().getgenericalarguments().Select(q=>q.Name).ToList() GoGeNyType定义()将返回null,因此您应该考虑这一点,我假设有一个条件。
    class MyClass<Tkey, Tvalue> { };


    private IEnumerable<string> GetTypeParameterNames(Type fType)
    {
        List<string> result = new List<string>();

        if(fType.IsGenericType)
        {
            var lGenericTypeDefinition = fType.GetGenericTypeDefinition();

            foreach(var lGenericArgument in lGenericTypeDefinition.GetGenericArguments())
            {
                result.Add(lGenericArgument.Name);
            }
        }

        return result;
    }

    private void AnalyseObject(object Object)
    {
        if (Object != null)
        {
            var lTypeParameterNames = GetTypeParameterNames(Object.GetType());
            foreach (var name in lTypeParameterNames)
            {
                textBox1.AppendText(name + Environment.NewLine);
            }
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        var object1 = new MyClass<string, string>();
        AnalyseObject(object1);

        var object2 = new List<string>();
        AnalyseObject(object2);

        AnalyseObject("SomeString");
    }