Bil*_*oks 4 c# inheritance generic-function
令人困惑的问题,我知道.鉴于以下内容:
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 { }
Run Code Online (Sandbox Code Playgroud)
以下代码生成有趣的输出:
DerivedType Derived = new DerivedType();
Derived.RunTest();
// output:
// typeof(T): BaseType
// SomeType.GetType(): DerivedType
Run Code Online (Sandbox Code Playgroud)
但是,这表现得如我所料:
Test.GenericFunc(new Derived());
// output:
// typeof(T): DerivedType
// SomeType.GetType(): DerivedType
Run Code Online (Sandbox Code Playgroud)
任何人都可以帮助我理解这里的机制导致T在第一种情况下被评估为BaseType吗?
提前致谢!
Eri*_*ert 14
除非涉及"动态"类型,否则在编译时执行重载决策和类型推断,而不是在运行时执行.
当重载决策看到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); }
}
Run Code Online (Sandbox Code Playgroud)
基本上相当于:
public class BaseType
{
public void RunTest() { Test.GenericFunc<BaseType>(this); }
}
Run Code Online (Sandbox Code Playgroud)
因此,GenericFunc在编译时获得实例化T = BaseType.但是,this您在运行时传入的对象是您获得的派生类型SomeType.GetType().
在第二种情况下,编译器DerivedType直接从使用中推断出类型,因此GenericFunc可以实现T = DerivedType.