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

C# 为什么开放泛型类型的基类型不开放?,c#,reflection,C#,Reflection,考虑下面的一段代码: public class A<T> { } public class B<T> : A<T> { } 其中b的值为1。因此,它是使用一个不存在的名称“T”类型关闭的,只有对它执行GetGenericTypeDefinition操作,它才能再次打开。这是为什么?该属性返回用作封闭泛型类型的泛型参数的类型,对于开放泛型类型,它返回emtpy数组 之所以typeof(B).BaseType.GenericTypeArguments不返回空数

考虑下面的一段代码:

public class A<T> { }

public class B<T> : A<T> { }
其中
b
的值为
1
。因此,它是使用一个不存在的名称“T”类型关闭的,只有对它执行
GetGenericTypeDefinition
操作,它才能再次打开。这是为什么?

该属性返回用作封闭泛型类型的泛型参数的类型,对于开放泛型类型,它返回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);
这表明
B
类型的
BaseType
确实是一个封闭类型,其泛型参数为类
a
的“虚拟”泛型类型

因此,它是使用一个不存在的名为“T”的类型关闭的,只有对它执行GetGenericTypeArgument操作,它才能再次打开。为什么呢

因为提供了一个类型参数--
B
的类型参数

看看您是如何指定基类的:

public class B<T> : A<T>
这里,
B
的基类是
A
,您可以通过询问类型参数来确定
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
    }
}
使用系统;
运用系统反思;
使用System.Collections.Generic;
公共A类{}
公共B类:A{}
班级计划
{
静态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
//显示B中的T与列表中的T不同
Console.WriteLine(bBaseArguments[0]==listT);//False
Console.WriteLine(bBaseArguments[1]==typeof(int));//True
}
}

System.Type类没有名为
GetGenericTypeArguments
的方法。你的意思是
getgenericalarguments
?@Wazner:是的,修正了。-我得到0和1。此外,
Console.WriteLine(typeof(B).BaseType.GenericTypeArguments[0]。FullName==null)为true。是的,我很抱歉,但我在我的示例中首先使用了错误的方法。请尝试当前的一个。还要注意,在使用泛型时,
MetadataToken
不是很好的标识符,因为所有
A
A
和例如
A
都将具有相同的值。具体的泛型实现是在运行时从相同的IL实体(因此具有相同的令牌)生成的。我唯一可以补充的是,您可以再次将其作为泛型类型定义(这也隐式地演示了它是如何工作的,因为它是:-)。例如:
typeof(B).BaseType.GetGenericTypeDefinition().GenericTypeArguments.Length
将再次为您提供0。
704643073
704643074
704643074
public class B<T> : A<T>
public class A<T1, T2> { }

public class B<T> : A<T, int> { }
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
    }
}