gpt4 book ai didi

c# - 编译器如何优化密封类实现的虚方法

转载 作者:太空宇宙 更新时间:2023-11-03 17:47:34 25 4
gpt4 key购买 nike

我想知道下面的代码是如何优化的。特别是关于虚拟和直接调用。我已经评论过我认为一切都已优化,但这些只是猜测。

public abstract class Super
{
public abstract void Foo();

public void FooUser()
{
Foo();
}
}

public class Child1 : Super
{
public override void Foo()
{
//doSomething
}
}

public class SealedChild : Super
{
public override void Foo()
{
//doSomething
}
}

class Program
{
void main()
{
Child1 child1 = new Child1();
child1.Foo(); //Virtual call?
child1.FooUser(); //Direct call and then a virtual call.

SealedChild sealedChild = new SealedChild();
sealedChild.Foo(); //Direct call?
sealedChild.FooUser();
/* Two options: either a direct call & then a virtual call
* Or: direct call with a parameter that has a function pointer to Foo, and then a direct call to foo.
*/

Super super = child1;
super.Foo(); //Virtual call.
super.FooUser(); //Virtual call then direct call.
}
}

最佳答案

如果密封类上有虚方法,并且对象引用的类型是密封类,则可以避免虚调用。以下面的例子为例。没有实际原因需要虚拟调用 GetName,因为我们知道不能有 Parent 的子类,因此没有进一步的虚拟分派(dispatch)。

sealed class Parent : Child  {
public override string GetName() { return "foo"; }
}

public void Test() {
var p = new Parent();
var name = p.GetName();
}

编译器可以选择注意到这一点并输出调用 IL 指令而不是 callvirt。然而,C# 和 VB.Net 编译器都选择不执行此优化。两者都会发出 callvirt。

JIT也可以自由地做这样的优化。它也选择不这样做。

但这并不意味着您不应该密封您的类(class)。类应该是密封的,除非你真的打算让某人继承它们。否则,您将面临无法准确计算成本的情况。

此外,没有什么可以阻止编译器和 JIT 在以后实现它。

关于c# - 编译器如何优化密封类实现的虚方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/770547/

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