为什么using语句中捕获闭包一个可变结构变量改变其本地的行为?
更新:好吧,现在我已经走了,做到了:我提起与微软的错误报告有关这一点,因为我严重怀疑,这是正确的行为。话虽如此,我还没有100%的把握相信什么就这个问题;这样我就可以看到什么是正确是开放的部分的间pretation水平。
Update: Well, now I've gone and done it: I filed a bug report with Microsoft about this, as I seriously doubt that it is correct behavior. That said, I'm still not 100% sure what to believe regarding this question; so I can see that what is "correct" is open to some level of interpretation.
我的感觉是,无论是微软会接受,这是一个错误,或者响应一个可变的值类型的变量中的修改使用
语句构成不确定的行为。
My feeling is that either Microsoft will accept that this is a bug, or else respond that the modification of a mutable value type variable within a using
statement constitutes undefined behavior.
另外,对于它的价值,我至少有一个的猜到的以这里发生了什么。我怀疑是编译器生成的类为关闭,揭的局部变量的类的实例字段;并且由于它是一个使用
块中,它使现场只读
。正如LukeH指出a评论其他问题,这将prevent方法调用,如的MoveNext
修改该字段本身(他们会代替影响副本)。
Also, for what it's worth, I have at least a guess as to what is happening here. I suspect that the compiler is generating a class for the closure, "lifting" the local variable to an instance field of that class; and since it is within a using
block, it's making the field readonly
. As LukeH pointed out in a comment to the other question, this would prevent method calls such as MoveNext
from modifying the field itself (they would instead affect a copy).
注:我已经缩短这个问题的可读性,但它仍然是不完全的短。对于全部原(长)的问题,请参见编辑历史。的
我已经经历了什么,我相信是ECMA-334的相关章节,似乎无法找到确凿的回答这个问题阅读。我会说明这个问题第一,然后提供一个链接到一些补充意见为那些有兴趣谁。
I have read through what I believe are the relevant sections of the ECMA-334 and cannot seem to find a conclusive answer to this question. I will state the question first, then provide a link to some additional comments for those who are interested.
如果我有一个实现的IDisposable
,我可以(1)调用,用于修改使用语句和code行为与我期望的那样。有一次,我抓住有问题的变量封闭的内内的的使用
语句,但是,(2)修改的值不再可见在当地的范围。
If I have a mutable value type that implements IDisposable
, I can (1) call a method that modifies the state of the local variable's value within a using
statement and the code behaves as I expect. Once I capture the variable in question inside a closure within the using
statement, however, (2) modifications to the value are no longer visible in the local scope.
这行为是在情况下,变量被抓获使用
语句中的关闭和里面唯一明显;这是看不出来的时候只有一个(使用
)或其它条件(关闭)是present。
This behavior is only apparent in the case where the variable is captured inside the closure and within a using
statement; it is not apparent when only one (using
) or the other condition (closure) is present.
使用
语句中为什么捕获可变的值类型的变量封闭内改变当地的行为?
Why does capturing a variable of a mutable value type inside a closure within a using
statement change its local behavior?
下面是code举例说明项目1和2两个例子都将采用下面的演示可变
值类型:
Below are code examples illustrating items 1 and 2. Both examples will utilize the following demonstration Mutable
value type:
struct Mutable : IDisposable
{
int _value;
public int Increment()
{
return _value++;
}
public void Dispose() { }
}
1。一个使用
块内变异值类型变量
1. Mutating a value type variable within a using
block
using (var x = new Mutable())
{
Console.WriteLine(x.Increment());
Console.WriteLine(x.Increment());
}
输出code输出:
The output code outputs:
0
1
2。一个使用
块中捕获的值类型变量闭包
2. Capturing a value type variable inside a closure within a using
block
using (var x = new Mutable())
{
// x is captured inside a closure.
Func<int> closure = () => x.Increment();
// Now the Increment method does not appear to affect the value
// of local variable x.
Console.WriteLine(x.Increment());
Console.WriteLine(x.Increment());
}
以上code输出:
The above code outputs:
0
0
更多评论
据指出,单声道编译器提供我期望的行为(改变局部变量的值仍然在使用
+封闭的情况可见)。无论这种行为的正确与否我不清楚。
Further Comments
It has been noted that the Mono compiler provides the behavior I expect (changes to the value of the local variable are still visible in the using
+ closure case). Whether this behavior is correct or not is unclear to me.
对于一些在这个问题上我更多的想法,看到here.
For some more of my thoughts on this issue, see here.
这是一个已知的bug;我们几年前发现了它。此修复程序的话会有潜在破坏,问题是pretty的晦涩难懂;这些都是反对将其固定点。因此,它从来没有被优先足够高,真正解决这个问题。
It's a known bug; we discovered it a couple years ago. The fix would be potentially breaking, and the problem is pretty obscure; these are points against fixing it. Therefore it has never been prioritized high enough to actually fix it.
这一直是我的潜力博客题目为一对夫妇现在的年队列;也许我应该把它写了起来。
This has been in my queue of potential blog topics for a couple years now; perhaps I ought to write it up.
和顺便说一句,你的猜想,以解释这个错误是完全正确的机制;好的心理调试那里。
And incidentally, your conjecture as to the mechanism that explains the bug is completely accurate; nice psychic debugging there.
所以,是的,已知的bug,但由于该报告无论!
So, yes, known bug, but thanks for the report regardless!