使用'this'从基类调用泛型函数参数时,它的参数类型是什么?
本文关键字:参数 是什么 类型 泛型 this 基类 调用 使用 函数 | 更新日期: 2023-09-27 18:02:02
我知道这是个令人困惑的问题。
class Test
{
public static void GenericFunc<T>(T SomeType)
{
System.Console.WriteLine("typeof(T): " + typeof(T).Name);
System.Console.WriteLine("SomeType.GetType(): " + SomeType.GetType().Name);
}
}
public class BaseType
{
public void RunTest() { Test.GenericFunc(this); }
}
public class DerivedType : BaseType { }
下面的代码产生有趣的输出:
DerivedType Derived = new DerivedType();
Derived.RunTest();
// output:
// typeof(T): BaseType
// SomeType.GetType(): DerivedType
然而,它的行为正如我所期望的:
Test.GenericFunc(new Derived());
// output:
// typeof(T): DerivedType
// SomeType.GetType(): DerivedType
谁能帮助我理解这里的机制,导致T被评估为BaseType在第一种情况下?
提前感谢!
除非涉及"动态"类型,否则在编译时执行重载解析和类型推断,而不是在运行时 。
当重载解析看到Test.GenericFunc(this);
时,它必须推断出与缺失的泛型类型形参对应的泛型类型实参。这是一个简单的问题;它使用this
的编译时间类型,并且在BaseType
的一个方法中,显然this
的编译时间类型始终是BaseType
。
因此,重载解析假定您打算调用Test.GenericFunc<BaseType>(this)
。
如果你想在运行时解决这个问题,你可以在c# 4中这样做。就说Test.GenericFunc((dynamic)this)
吧。这将在运行时再次启动重载解析引擎,然后它将假装您在编译时将this
转换为其运行时类型。
是的,那和听起来一样贵。如果你想在运行时进行语义分析,那么我们必须在运行时运行语义分析器
因为:
public class BaseType
{
public void RunTest() { Test.GenericFunc(this); }
}
基本上相当于:
public class BaseType
{
public void RunTest() { Test.GenericFunc<BaseType>(this); }
}
因此GenericFunc
在编译时与T = BaseType
一起被初始化。但是,您在运行时传递的this
对象是您通过SomeType.GetType()
获得的派生类型。
在第二种情况下,编译器直接从用法中推断类型为DerivedType
,因此GenericFunc
被T = DerivedType
初始化。