下面的代码在不可变结构中包含一个简单的LINQ查询.
struct Point
{
static readonly List</*enum*/> NeighborIndexes;
//and other readonly fields!
public IEnumerable<FlatRhombPoint> GetEdges()
{
return from neighborIndex in NeighborIndexes;
select GetEdge(neighborIndex);
}
}
Run Code Online (Sandbox Code Playgroud)
它不编译.
结构体内的匿名方法,lambda表达式和查询表达式无法访问"this"的实例成员.考虑将'this'复制到匿名方法,lambda表达式或查询表达式之外的局部变量,并使用local.
有谁知道为什么不允许这样做?
修复消息建议工作正常:
public IEnumerable<FlatRhombPoint> GetEdges()
{
var thisCopy = this;
return from neighborIndex in NeighborIndexes;
select thisCopy.GetEdge(neighborIndex);
}
Run Code Online (Sandbox Code Playgroud)
但这是标准做法吗?是否有理由在结构中没有这样的查询?(在制作副本的更大方案中,并不担心我的表现如此).
SLa*_*aks 20
在结构实例方法调用一个参考来this- 一个隐藏的ref参数.
这就是结构方法能够改变它们被调用的结构的原因.
在thislambda表达式或LINQ查询中使用(或任何其他局部变量/参数)时,编译器会将其转换为编译器生成闭包类的字段.
CLR不支持ref字段,因此捕获this的工作方式不可能与常规工作方式相同this.(这也是你不能ref在lambdas中使用参数的原因)
迭代器方法具有相同的问题 - 它们被编译成隐藏的枚举器类,并且所有变量或参数都成为类中的字段(这就是迭代器不能接受ref参数的原因).
但是,对于迭代器,C#做出了相反的决定.在迭代器中,您可以使用this,但它将被复制到枚举器类的字段中.
这意味着如果你在迭代器中改变一个结构,突变将不会发生在调用者的副本中.
| 归档时间: |
|
| 查看次数: |
591 次 |
| 最近记录: |