我为什么要复制“本”在一个结构时使用LINQ(并且是它确定,如果我这样做)?(Why do I ha

2019-07-23 07:04发布

该代码初级讲座中包含不可变的结构里面一个简单的LINQ查询。

struct Point
{
   static readonly List</*enum*/> NeighborIndexes;
   //and other readonly fields!

    public IEnumerable<FlatRhombPoint> GetEdges()
    {
        return from neighborIndex in NeighborIndexes;
             select GetEdge(neighborIndex);
    }
}

它不编译。

匿名方法,lambda表达式和内部结构查询表达式无法访问“这个”实例成员。 考虑复制“这个”匿名方法,lambda表达式或查询表达式之外的局部变量和使用本地代替。

是否有任何人知道为什么这是不允许的?

该修复程序的消息表明,正常工作:

    public IEnumerable<FlatRhombPoint> GetEdges()
    {
        var thisCopy = this;

        return from neighborIndex in NeighborIndexes;
             select thisCopy.GetEdge(neighborIndex);
    }

但是,这是标准的做法? 有没有理由不具有结构类似这样的疑问? (在事情进行复印更大的计划并不担心我的表现明智如此)。

Answer 1:

在结构实例方法调用一个参考 this - 一个隐藏的ref参数 。
这就是为什么结构方法能够变异,他们是所谓的结构。

当使用this (或任何其它局部变量/参数)lambda表达式或LINQ查询内,则编译器将其转换上的一个字段编译器产生闭合类 。

在CLR不支持ref领域,所以这将是不可能的捕捉到this工作方式与常规的同this 。 (这也是不能使用的原因ref内部lambda表达式参数)

迭代方法有同样的问题-它们被编译成一个隐藏的枚举器类,以及所有变量或参数成为类的字段(这就是为什么迭代器不能采取ref参数)。
然而,对于迭代器,C#做出相反的决定。 内部的迭代器,你可以用this ,但它会被复制到枚举器类的字段。
这意味着,如果发生变异的迭代器内部的结构,该突变不会发生在调用者的副本。



文章来源: Why do I have to copy “this” when using LINQ in a struct (and is it OK if I do)?
标签: c# linq struct