如果我有:
var myObjects = new ConcurrentBag<object>();
并尝试通过以下方式删除对象:
foreach (var myObject in myObjects.ToArray()) { myObjects.TryTake(out myObject); }
编译器抱怨:“只读本地变量不能用作赋值目标”
然而,如果我在foreach中添加一个本地引用,它会编译:
foreach (var myObject in myObjects.ToArray()) { var localReference = myObject; myObjects.TryTake(out localReference); }
这里究竟发生了什么?
解决方法
foreach中的迭代变量(即myObject)不能在foreach内部分配一个新值.不允许.
在第一种情况下,外部尝试这样做.在第二种情况下,你永远不会尝试重新分配给myObject,所以没关系.
引用ECMA规范,15.8.4,强调我的:
The type and identifier of a foreach statement declare the
iteration variable of the statement.The iteration variable corresponds to a read-only local
variable with a scope that extends over the embedded statement.During execution of a foreach statement,the iteration variable
represents the collection element for which an iteration is
currently being performed.A compile-time error occurs if the embedded statement attempts
to modify the iteration variable (via assignment or the ++ and
–operators) or pass the iteration variable as a ref or out parameter.