为什么我要复制"本"在一个结构时使用LINQ(和它确定,如果我这样做)? [英] Why do I have to copy "this" when using LINQ in a struct (and is it OK if I do)?
问题描述
中的代码初级讲座包含一个不变的结构里面一个简单的LINQ查询。
The code belows contains a simple LINQ query inside an immutable struct.
struct Point
{
static readonly List</*enum*/> NeighborIndexes;
//and other readonly fields!
public IEnumerable<FlatRhombPoint> GetEdges()
{
return from neighborIndex in NeighborIndexes;
select GetEdge(neighborIndex);
}
}
它不能编译。
It does not compile.
匿名方法,lambda表达式和
结构内查询表达式无法访问的本的实例成员。考虑复制
'这个'匿名方法之外的局部变量,拉姆达
表达式或查询表达式并使用本地代替。
Anonymous methods, lambda expressions, and query expressions inside structs cannot access instance members of 'this'. Consider copying 'this' to a local variable outside the anonymous method, lambda expression or query expression and using the local instead.
任何一个是否知道这是为什么不允许
该修复的消息表明,正常工作:
The fix the message suggests works fine:
public IEnumerable<FlatRhombPoint> GetEdges()
{
var thisCopy = this;
return from neighborIndex in NeighborIndexes;
select thisCopy.GetEdge(neighborIndex);
}
但是,这是标准的做法?有没有理由不具有结构这样的疑问?
(在物联网制作副本更大的计划并不担心我的表现明智这样)。
But is this standard practice? Are there reasons for not having queries like this in structs? (In the bigger scheme of things making a copy does not worry me performance-wise as such).
推荐答案
在结构实例方法调用一个的参考到这个
&ndash的; 隐藏 REF
参数。结果
这就是为什么结构方法能够变异他们是所谓的结构。
Instance methods on structs are called with a reference to this
– a hidden ref
parameter.
This is why struct methods are able to mutate the structs they're called on.
当您使用这个
(或任何其它局部变量/参数)lambda表达式或LINQ查询里面,编译器把它变成一个字段上的编译器生成封类。
When you use this
(or any other local variable / parameter) inside a lambda expression or LINQ query, the compiler turns it into a field on a compiler-generate closure class.
CLR不支持 REF
字段,因此为拍摄这将是不可能的这个
来的工作方式相同作为常规这个
。 (这也是你不能使用的原因里面的lambda参考
参数)
The CLR does not support ref
fields, so it would be impossible for the captured this
to work the same way as a regular this
. (this is also the reason that you can't use ref
parameters inside lambdas)
迭代方法具有相同的问题&ndash的;它们被编译成一个隐藏的枚举器类,以及所有变量或参数成为类的字段(这就是为什么迭代器不能采取 REF
参数)。结果
然而,对于迭代器,C#做出相反的决定。内部迭代器,你可以使用这个
,但它会被复制到枚举器类的字段。结果
这意味着,如果发生变异,一个迭代器内的结构,基因突变不会发生在调用者的副本。
Iterator methods have the same issue – they are compiled into a hidden enumerator class, and all variables or parameters become fields in the class (this is why iterators cannot take ref
parameters).
However, for iterators, C# made the opposite decision. Inside an iterator, you can use this
, but it will be copied to a field on the enumerator class.
This means that if you mutate a struct inside an iterator, the mutations will not happen to the caller's copy.
这篇关于为什么我要复制"本"在一个结构时使用LINQ(和它确定,如果我这样做)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!