gpt4 book ai didi

c# - 抽象类中 'this'的类型和重载方法解析顺序困惑

转载 作者:行者123 更新时间:2023-11-30 07:26:06 25 4
gpt4 key购买 nike

这个非常简单的例子让我感到困惑:

public class X {
public void XMethod(A a) {
Console.WriteLine(a.GetType());
Console.WriteLine("Got A");
}

public void XMethod(B b) {
Console.WriteLine(b.GetType());
Console.WriteLine("Got B");
}
}

public abstract class A {
public virtual void M(X x) {
Console.WriteLine(this.GetType());
x.XMethod(this);
}
}

public class B : A {

}

class Program {
static void Main(string[] args) {
X x = new X();
B b = new B();
b.M(x);
}
}

这个的输出是

B
B
Got A

“Got A”之前的一切都很好。当我在类 B 的实例上调用方法 M 时,我希望方法 X.XMethod(B) 会被调用。

这是怎么回事?为什么调用 XMethod(A) 而不是 XMethod(B),当很明显提供的参数类型是 B 而不是 A?

PS:我在 java 中得到了相同的输出以实现等效的实现。

最佳答案

只有A.M方法。不是一个用于A,一个用于B

A.M 中的 IL 对于所有实例都是相同的;在编译时,A.M 只知道 thisA(或 object),因此它解析 总是XMethod(A)。此方法解析在编译时生成的 IL 中,不会为子类更改(实际上,子类可能位于编译器甚至不知道的单独程序集中):

.method public hidebysig newslot virtual instance void M(class X x) cil managed
{
.maxstack 8
L_0000: ldarg.0
L_0001: call instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
L_0006: call void [mscorlib]System.Console::WriteLine(object)
L_000b: ldarg.1
L_000c: ldarg.0
L_000d: callvirt instance void X::XMethod(class A)
L_0012: ret
}

要获得所需的行为,您可以使用dynamic。不过,并不是说您应该

关于c# - 抽象类中 'this'的类型和重载方法解析顺序困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10578037/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com