为什么我要复制"本"在一个结构时使用LINQ(和它确定,如果我这样做)? [英] Why do I have to copy "this" when using LINQ in a struct (and is it OK if I do)?

查看:158
本文介绍了为什么我要复制"本"在一个结构时使用LINQ(和它确定,如果我这样做)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

中的代码初级讲座包含一个不变的结构里面一个简单的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.

这篇关于为什么我要复制&QUOT;本&QUOT;在一个结构时使用LINQ(和它确定,如果我这样做)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆