Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 获取泛型类型参数的数量_C#_.net_Generics_Reflection - Fatal编程技术网

C# 获取泛型类型参数的数量

C# 获取泛型类型参数的数量,c#,.net,generics,reflection,C#,.net,Generics,Reflection,有没有办法获取未绑定泛型类型中的参数数? 例如: f(typeof(List<>)) => 1 f(typeof(Dictionary<,>)) => 2 void Main() { typeof(A<>.Nested<>).GetGenericArguments().Dump(); } public class A<T> { public class Nested<V> {

有没有办法获取未绑定泛型类型中的参数数? 例如:

f(typeof(List<>))        => 1
f(typeof(Dictionary<,>)) => 2
void Main()
{
  typeof(A<>.Nested<>).GetGenericArguments().Dump();
}

public class A<T>
{
  public class Nested<V>
  {

  }
}
f(typeof(List))=>1
f(字典的类型)=>2
UPD


我知道如何从Type.Name中获取数字,但也许有一种方法可以直接从Type中获取

您已经有了泛型类型定义。您只需获取泛型类型参数:

Type.GetGenericArguments().Length
编辑

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

f(typeof(List<>))        => 1
f(typeof(Dictionary<,>)) => 2
void Main()
{
  typeof(A<>.Nested<>).GetGenericArguments().Dump();
}

public class A<T>
{
  public class Nested<V>
  {

  }
}
void Main()
{
typeof(A.Nested).GetGenericArguments().Dump();
}
公共A类
{
公共类嵌套
{
}
}
将给您
{typeof(T),typeof(V)}
。这就是.NET类的实际情况-这就是您需要如何引用它,如何通过反射创建它等等

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

不适用于嵌套类型

例如,如果您有
OuterClass.InnerClass
的话,人们会期望
1
参数,但是.NET实际上报告了
3

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

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);
}
public static int GetGenericParameterCount(类型)
{
如果(!type.IsGenericType)
{
返回0;
}
var genericTypeDefName=type.GetGenericTypeDefinition().Name;
int tickIndex=genericTypeDefName.LastIndexOf('`');
如果(滴答声指数==-1)
{
//对于嵌套类型,如“OuterClass.InnerClass”,将发生这种情况。
返回0;
}
返回int.Parse(genericTypeDefName.Substring(tickIndex+1),NumberStyles.None);
}
计算通用参数的总数 只需查询
t.GetGenericArguments().Length
即可找到某种类型的
t
的泛型参数(或参数)的总数:

static int GenericParameterCount(此类型为t)
=>t.IsGenericType?t、 GetGenericArguments().Length
: 0;
仅嵌套类型:计算“本地”泛型参数的数量(不包括从外部类型继承的参数) 对嵌套类型执行上述操作可能会得到最初令人惊讶的结果。例如,type
Outer.Inner
有1个泛型参数,type
Outer.Inner
有2个泛型参数。只要您只将这些嵌套类型视为
内部
内部
(即它们在源代码中的声明方式),这似乎是不正确的

(出于同样的原因,您最初可能会惊讶地发现
typeof(Outer.Inner).IsGenericType==true
,即使查询的类型
Inner
看起来不是泛型。)

如果确实要仅计算“本地”泛型类型参数并排除从其外部类型继承的参数,只需减去外部类型(
type.DeclaringType
)的泛型参数总数:

static int LocalGenericParameterCount(此类型为t)
=>t.IsNested?t、 GenericParameterCount()-t.DeclaringType.GenericParameterCount()
:t.GenericParameterCount();

您对
类型
暴露的操作做了哪些研究,可能允许您这样做?术语:类型接受的泛型参数数量称为该类型的
泛型arity
。请注意,这可能不适用于嵌套类型;e、 对于
OuterClass.InnerClass
你会得到
3
,而不是
1
@SebastianKrysmanski,这取决于你到底想要什么。内部类确实有三个泛型类型参数,只是C#隐藏了从更高的类“继承”的参数。如果你想复制C#行为,你需要更加努力:)@Luaan:+1。关于答案的最后一段:计算嵌套类型的“非继承”泛型参数的数量实际上相当简单(只需另一个查询和一个减法);请参阅的后半部分。嵌套类确实有三个泛型类型参数。因此,除非您特别想要C#编译器具有的相同行为,否则三是正确答案。解析类型名的问题在于没有定义您所依赖的行为-编译器可以随时更改生成类型名的方式,更不用说其他.NET语言有不同的约定。无需解析字符串。您可以从
type.GetGenericArguments().Length
开始获得相同的数字,如果是嵌套类型,则减去外部类型的相同度量(
type.DeclaringType
)。看见