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;
仅嵌套类型:计算“本地”泛型参数的数量(不包括从外部类型继承的参数)
对嵌套类型执行上述操作可能会得到最初令人惊讶的结果。例如,typeOuter.Inner
有1个泛型参数,typeOuter.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
)。看见