gpt4 book ai didi

c# - 错误的 C# 编译器警告?

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

好吧,这是我们偶然发现的一个很长的角落案例,但这让我很好奇。

考虑以下代码:

public class Foo
{
private int foo;
public int Reset() => foo = 0; //remember, assignment expressions
//return something!
}

这段代码可以编译吗?

不,如果您在所有警告上都失败了,它就不会;你会得到一个 member foo is assigned but never used 警告。

就所有目的而言,此代码与:

public class Foo
{
private int foo;
public int Reset() { foo = 0; return foo; }
}

哪个编译得很好,那么这里的问题是什么?请注意,=> 语法不是问题,它返回的赋值表达式似乎让编译器感到困惑。

最佳答案

在第一个例子中,foo 被赋值,但从未被读取。 0 被分配给 foo,然后返回 0,无论 foo 的值是什么(例如如果另一个线程同时改变了它)。

在第二个例子中,foo 被赋值,然后从中读取。如果同时有另一个线程修改了foo,则返回修改后的值,而不是0

您可以通过比较已编译的 IL 来了解实际情况。给定以下代码:

public class Foo
{
private int foo;
public int Reset() { return (foo = 0); }
public int Reset2() { foo = 0; return foo; }
}

以下 IL 是为 ResetReset2 编译的。

.method public hidebysig 
instance int32 Reset () cil managed
{
.maxstack 3
.locals init (
[0] int32
)

IL_0000: ldarg.0
IL_0001: ldc.i4.0
IL_0002: dup
IL_0003: stloc.0
IL_0004: stfld int32 Foo::foo
IL_0009: ldloc.0
IL_000a: ret
}

.method public hidebysig
instance int32 Reset2 () cil managed
{
.maxstack 8

IL_0000: ldarg.0
IL_0001: ldc.i4.0
IL_0002: stfld int32 Foo::foo
IL_0007: ldarg.0
IL_0008: ldfld int32 Foo::foo
IL_000d: ret
}

Reset中,我们只存储到Foo::foo (stfld)。

Reset2 中,您可以看到我们既存储到它又从它加载 (stfld + ldfld)。

关于c# - 错误的 C# 编译器警告?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47046489/

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