[英]Why is the base type of an open generic type not open?
考虑下面的一段代码:
public class A<T> { }
public class B<T> : A<T> { }
在这种情况下:
var a = typeof(A<>).GenericTypeArguments.Length;
a
的值为0
,这并不奇怪。 然而,这对我来说是出乎意料的:
var b = typeof(B<>).BaseType.GenericTypeArguments.Length;
其中b
的值为1
。 因此,它使用不存在的名称“T”关闭,并且仅对其执行GetGenericTypeDefinition
使其再次打开。 这是为什么?
因此,它使用不存在的类型名称“T”关闭,只对其执行GetGenericTypeArgument使其再次打开。 这是为什么?
因为提供一种类型的参数-类型参数B
。
看看你是如何指定基类的:
public class B<T> : A<T>
什么是T
的A<T>
如果它不是一个类型参数? 仅仅因为类型参数本身是一个类型参数并不意味着它没有被指定为类型参数。
考虑一下:
public class A<T1, T2> { }
public class B<T> : A<T, int> { }
这里, B<T>
的基类是A<T, int>
- 你可以通过询问类型参数来确定是否已经指定了int
。 您还可以显示T
来自何处:
using System;
using System.Reflection;
using System.Collections.Generic;
public class A<T1, T2> { }
public class B<T> : A<T, int> { }
class Program
{
static void Main()
{
var bT = typeof(B<>).GetTypeInfo().GenericTypeParameters[0];
var listT = typeof(List<>).GetTypeInfo().GenericTypeParameters[0];
var bBaseArguments = typeof(B<>).BaseType.GenericTypeArguments;
Console.WriteLine(bBaseArguments[0] == bT); // True
// Shows that the T from B<T> isn't the same as the T from List<T>
Console.WriteLine(bBaseArguments[0] == listT); // False
Console.WriteLine(bBaseArguments[1] == typeof(int)); // True
}
}
Type.GenericTypeArguments属性返回用作封闭泛型类型的泛型参数的类型,对于开放泛型类型,它返回一个emtpy数组。
typeof(B<>).BaseType.GenericTypeArguments
不返回空数组的原因是因为它不是开放的泛型类型。
为了说明这种行为,我使用Type.MetadataToken
来识别类型。
Console.WriteLine(typeof(A<>).GetGenericArguments()[0].MetadataToken);
Console.WriteLine(typeof(B<>).GetGenericArguments()[0].MetadataToken);
Console.WriteLine(typeof(B<>).BaseType.GetGenericArguments()[0].MetadataToken);
这将在屏幕上打印以下内容(数字会有所不同,但相等性将保持不变):
704643073
704643074
704643074
这表明类型B<>
的BaseType
确实是一个封闭类型,其通用参数是类A<>
的“虚拟”泛型类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.