将 null 传递给泛型方法时,奇怪的是我仍然可以获得类型

When null is passed into generic method, strangely I can still get the type

我在玩一些泛型,无意中发现了一些非常有趣的东西。请查看此行的代码 Console.WriteLine(testClass1.Contains(testClass));产生输出:true。我不知道为什么,因为 class 被分配给 null,当我进入代码时,我可以看到传入了 null。

    private static void Main(string[] args)
    {
        ClassWithGenericMethod testClass1 = new ClassWithGenericMethod();
        TestClass testClass = null;

        Console.WriteLine(testClass1.Contains(testClass));

        Console.ReadKey();
    }

    public class ClassWithGenericMethod
    {
        public bool Contains<T>(T entity)
        {
            return typeof(T).Name == "TestClass";
        }
    }

    public class TestClass
    {
    }

那么它如何知道这一行的正确类型 return typeof(T).Name == "TestClass"; ?

泛型方法的类型不会在 运行 时解析,它们会在编译时解析。编译器知道当您调用 Contains<T> 时,您是使用类型 TestClass 的参数调用它,因此编译器使用完整的泛型方法 Contains<TestClass>。该值是否为 null 是一个 运行 时间条件,与编译器在编译代码时的知识无关。

通俗地说,泛型方法实际上是一种函数模板(或"definition"),"real"方法将从该定义构造。例如,如果您调用

之类的方法
Contains<string>(null);

.NET 编译器将确保以下方法构造(或有点类似)

public bool Contains(string entity)
{
    return typeof(string).Name == "TestClass";
}

您可以看到所有 T 都被替换为 string,这使得该方法使用 T 类型完全合法并且不需要运行时检查entity 参数。