我的 C# 源代码中有以下场景:
class A{}
class Dispatch<T>{}
static class DispatchExt
{
public static void D<T>(this Dispatch<T> d, int a)
{
Console.WriteLine("Generic D chosen with a = " + a.ToString());
}
public static void D(this Dispatch<A> d, int a)
{
Console.WriteLine("D<A> chosen with a = " + a.ToString());
}
}
class Program
{
static void D<T>(Dispatch<T> d, int a)
{
d.D(a);
}
static void Main(string[] args)
{
int a = 5;
var dispatch = new Dispatch<A>();
dispatch.D(a);
D(dispatch, a);
}
}
当我运行此代码时,输出是:
"D<A>
选择 a = 5"
“通用的D
选择 a = 5"
这个结果让我很惊讶,因为我在期待“D<A>
在这两种情况下都选择 a = 5"。
我想知道这种情况下的一般重载解析规则是什么,或者导致此输出的任何内容。此外,我想知道是否有办法在这两种情况下实现第一个输出。
扩展方法是在编译时仅使用从静态类型系统获取的信息进行解释的语法糖。
以你的第一个例子为例,你有这样的:
dispatch.D(a);
dispatch
属于类型Dispatch<A>
,存在一个扩展方法。所以编译器将其翻译为DispatchExt.D(dispatch, a)
(非通用版本)。
在你的第二个例子中,你有这样的:
d.D(a);
d
属于类型Dispatch<T>
。所以这需要通用扩展方法DispatchExt.D<T>(d, a)
.
由于翻译发生在编译时,因此不考虑实际的运行时类型。
顺便说一句,这是。在其他情况下确定重载时使用相同的行为:仅考虑静态编译时类型:
A a = new A();
B b = new B();
A ba = b;
Test(a); // "a"
Test(b); // "b"
Test(ba); // "a"
使用以下定义:
public void Test(A a) { Console.WriteLine("a"); }
public void Test(B a) { Console.WriteLine("b"); }
public class A {}
public class B : A {}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)