gpt4 book ai didi

c# - C# 和 VB 如何处理命名参数之间的差异?

转载 作者:IT王子 更新时间:2023-10-29 04:44:05 25 4
gpt4 key购买 nike

现在 C# 支持命名参数,我正在检查它是否以与 VB 相同的方式实现,并发现存在细微差别。以这样的库函数为例:

public static void Foo(string a, string b)
{
Console.WriteLine(string.Format("a: {0}, b: {1}", a, b));
}

在 C# 中,如果你这样调用它:

Foo(a: "a", b: "b");

编译器生成以下 IL 指令:

.locals init (
[0] string CS$0$0000,
[1] string CS$0$0001)
L_0000: nop
L_0001: ldstr "a"
L_0006: stloc.0
L_0007: ldstr "b"
L_000c: stloc.1
L_000d: ldloc.0
L_000e: ldloc.1
L_000f: call void [TestLibrary]TestLibrary.Test::Foo(string, string)
L_0014: nop
L_0015: ret

转换为以下 C# 代码:

string CS$0$0000 = "a";
string CS$0$0001 = "b";
Test.Foo(CS$0$0000, CS$0$0001);

在VB中,如果这样调用:

Foo(a:="a", b:="b")

编译器生成以下 IL 指令:

L_0000: nop 
L_0001: ldstr "a"
L_0006: ldstr "b"
L_000b: call void [TestLibrary]TestLibrary.Test::Foo(string, string)
L_0010: nop
L_0011: nop
L_0012: ret

转换为以下 VB 代码:

Foo("a", "b");

VB 的实现方式需要更少的指令调用,那么 C# 的实现方式有什么优势吗?如果不使用命名参数,C# 会产生与 VB 相同的结果。


编辑:既然我们已经确定额外的指令在 Release模式下消失了,那么它们在 Debug模式下出现是否有特殊原因? VB 在两种模式下的行为相同,并且 C# 在正常调用不带命名参数的方法时(包括使用可选参数时)不会插入额外的指令。

最佳答案

is there a particular reason for them to be present in debug mode?

区别在于:

  • 将一个临时值压入堆栈,使用它,丢弃它,然后
  • 将临时值存储到特定的栈槽中,将其复制到栈上,使用它,丢弃它,但临时值的原始副本保留在栈槽中

这种差异的明显影响是垃圾收集器无法积极清理该值。在第一种情况下,调用返回后可以立即收集该值。在第二种情况下,只有在当前方法返回(或重新使用插槽)后才收集该值。

降低垃圾收集器的积极性通常有助于调试场景。

隐含的问题是:

Why the difference between C# and VB?

C# 和 VB 编译器是由不同的人编写的,他们对各自代码生成器的工作方式做出了不同的选择。

更新:回复:您的评论

在 C# 编译器中,未优化的 IL 生成本质上与我们的功能内部表示具有相同的结构。当我们看到命名参数时:

M(y : Q(), x : R());

方法在哪里,比如说

void M(int x, int y) { }

我们在内部表示这个就像你写的一样

int ytemp = Q();
int xtemp = R();
M(xtemp, ytemp);

因为我们想保留 Q 和 R 的副作用的从左到右的评估。这是一个合理的内部表示,当我们在非优化模式下对其进行编码时,我们直接从几乎没有任何修改的内部表示。

当我们运行优化器时,我们会检测到各种各样的东西——例如没有人将那些不可见的局部变量用于任何事情这一事实。然后我们可以从代码生成中消除本地人。

我对 VB 内部表示知之甚少;自 1995 年以来我就没有研究过 VB 编译器,而且我听说它在过去十五年中可能发生了轻微的变化。我想他们会做类似的事情,但我不知道他们如何表示命名参数或他们的代码生成器如何处理它们的细节。

我的观点是,据我所知,这种差异并不能说明重要的语义差异。相反,它说明未经优化的构建只是吐出我们碰巧生成的我们知 Prop 有所需语义的任何高级内部表示。

关于c# - C# 和 VB 如何处理命名参数之间的差异?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2331620/

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