gpt4 book ai didi

c# - 为什么在结构中使用 LINQ 时必须复制 "this"(如果我这样做可以)?

转载 作者:可可西里 更新时间:2023-11-01 03:08:40 25 4
gpt4 key购买 nike

下面的代码在不可变结构中包含一个简单的 LINQ 查询。

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

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

它不编译。

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.

有谁知道为什么不允许这样做?

消息建议的修复工作正常:

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

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

但这是标准做法吗?是否有理由在结构中没有这样的查询?(在更大的计划中,制作副本不会让我担心性能方面的问题)。

最佳答案

结构上的实例方法通过对 thisreference 调用 – a hidden ref parameter .
这就是结构方法能够改变调用它们的结构的原因。

当您在 lambda 表达式或 LINQ 查询中使用 this(或任何其他局部变量/参数)时,编译器会将其转换为 compiler-generate closure class 上的字段.

CLR 不支持 ref 字段,因此捕获的 this 不可能像常规 this 一样工作. (这也是你不能在 lambda 中使用 ref 参数的原因)

迭代器方法有同样的问题——它们被编译成一个隐藏的枚举器类,所有变量或参数都成为类中的字段(这就是迭代器不能接受ref参数的原因)。
但是,对于迭代器,C# 做出了相反的决定。在迭代器中,你 can use this , 但它将被复制到枚举器类上的一个字段。
这意味着如果您在迭代器内改变结构,则改变不会发生在调用者的副本上。

关于c# - 为什么在结构中使用 LINQ 时必须复制 "this"(如果我这样做可以)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15619407/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com