获取泛型类型参数的数目

本文关键字:泛型类型参数 获取 | 更新日期: 2023-09-27 17:59:46

是否有任何方法可以获取未绑定泛型类型中的参数数量?例如:

f(typeof(List<>))        => 1
f(typeof(Dictionary<,>)) => 2

UPD

我知道如何从Type中获取数字。名称,但可能有一种方法可以直接从类型中获取

获取泛型类型参数的数目

您已经有了泛型类型定义。您所需要做的就是获取泛型类型参数:

Type.GetGenericArguments().Length

编辑

正如Sebastian所指出的,如果你习惯于处理C#,这可能会给你带来令人惊讶的结果,因为C#隐藏了"继承"的泛型类型参数。例如:

void Main()
{
  typeof(A<>.Nested<>).GetGenericArguments().Dump();
}
public class A<T>
{
  public class Nested<V>
  {
  }
}

会给你{ typeof(T), typeof(V) }。这就是简单的方式。NET类实际上是-这就是你需要引用它的方式,你将如何通过反射等创建它。

只有当您特别尝试使用C#编译器对编译时未知的类执行某些操作时,这才重要;这可能意味着您正在尝试生成C#代码。似乎没有任何支持的方法可以安全地获得C#的行为-你只需要使用一个真正的代码生成器,而不是将字符串拼凑在一起:)

Luaan的答案不适用于嵌套类型。

例如,如果您有OuterClass<,>.InnerClass<>,则会期望1参数,但是。NET实际报告CCD_ 4。

我发现解决这个问题的唯一方法是解析泛型类型定义的名称,如下所示:

public static int GetGenericParameterCount(Type type)
{
    if (!type.IsGenericType)
    {
        return 0;
    }
    var genericTypeDefName = type.GetGenericTypeDefinition().Name;
    int tickIndex = genericTypeDefName.LastIndexOf('`');
    if (tickIndex == -1)
    {
        // This will happen for nested types like "OuterClass<int>.InnerClass".
        return 0;
    }
    return int.Parse(genericTypeDefName.Substring(tickIndex + 1), NumberStyles.None);
}

计算泛型参数的总数

只需查询t.GetGenericArguments().Length,即可找到某些类型t:的泛型参数(或自变量)的总数

static int GenericParameterCount(this Type t)
    => t.IsGenericType ? t.GetGenericArguments().Length
                       : 0;

仅嵌套类型:计算"本地"泛型参数的数量(不包括从外部类型继承的参数)

对嵌套类型执行上述操作可能会产生最初令人惊讶的结果。例如,类型Outer<T>.Inner有1个泛型参数,类型Outer<T>.Inner<U>有2个。只要您只将这些嵌套类型视为InnerInner<U>(即它们在源代码中的声明方式),这可能看起来是不正确的。

(出于同样的原因,您最初可能会惊讶地发现typeof(Outer<T>.Inner).IsGenericType == true,尽管查询的类型Inner似乎不是通用的。)

如果您真的想只计算"本地"泛型类型参数并排除从其外部类型继承的参数,您可以简单地减去外部类型(type.DeclaringType)的泛型参数总数:

static int LocalGenericParameterCount(this Type t)
    => t.IsNested ? t.GenericParameterCount() - t.DeclaringType.GenericParameterCount()
                  : t.GenericParameterCount();