在一本书中发现了这一点,但是解释太短了。
public class Program
{
int a = 0;
private static void Main()
{
var val = new Program();
val.a += val.Foo();
Console.WriteLine(val.a);
Console.ReadKey();
}
private int Foo()
{
a = a + 42;
return 1;
}
}
是否需要对拳击做一些事情?
答案 0 :(得分:5)
这与拳击无关,这是操作顺序...
class Program
{
int a = 0;
static void Main()
{
Program val = new Program();
val.a += val.Foo();
Console.WriteLine(val.a);
Console.ReadKey();
}
int Foo()
{
a = a + 42;
return 1;
}
}
所以发生了什么
val.a += val.Foo();
基本上被重写为
val.a = val.a + val.Foo();
由于操作的顺序,这就是要压入堆栈的内容:
val.a = 0 val.Foo = 1
因此,当val.a += val.Foo()
的求值开始时,它将保存val.a
的当前值为零,然后调用该函数。该函数会修改val.a
,但是由于它是一个值类型,因此它不会更新原始调用方中保存的值。 val.Foo()
返回后,等式变为val.a = 0 + 1
,因此结果为1
,而不是43
。
如果将其稍作重写,则会得到不同的结果:
val.a = val.Foo() + val.a;
然后将得到43。这是一个操作顺序问题。
答案 1 :(得分:3)
让我们看看:
// val.a = 0
Program val = new Program();
// val.a += val.Foo() can be rewritten as
// val.a = val.a + val.Foo() or initial value of val.a + result of val.Foo()
// val.a = 0 + 1
val.a += val.Foo();
// print out 1
Console.WriteLine(val.a);
编辑::如果您想利用副作用(在a
方法中将42
分配给Foo()
),可以放置(而不是val.a = val.a + val.Foo()
):
// result of val.Foo + current val.a value
// 1 + 42 == 43
val.a = val.Foo() + val.a;
答案 2 :(得分:-1)
在Foo()
上,您始终返回1。
正确的代码:
int Foo()
{
a = a + 42;
return a;
}