为什么开放泛型类型的基类型不开放?
本文关键字:类型 泛型类型 为什么 基类 | 更新日期: 2023-09-27 18:08:45
考虑下面的一段代码:
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>
如果A<T>
不是类型参数,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
}
}
字体。GenericTypeArguments属性返回作为封闭泛型类型的泛型形参的类型,对于打开泛型类型,它返回一个空数组。
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<>
的"虚拟"泛型。