为什么开放泛型类型的基类型不开放?

本文关键字:类型 泛型类型 为什么 基类 | 更新日期: 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<>的"虚拟"泛型。