当前位置: 首页 > 编程语言 > C#

为什么结构体内的匿名方法无法访问’this’的实例成员分享

时间:2023-04-11 01:27:13 C#

C#学习教程:为什么结构体中的匿名方法不能访问'this'的实例成员voidSomeMethod(){varitems=Enumerable.Range(0,10).Where(i=>i==_field);}诠释字段;...然后我得到以下编译器错误:结构内的匿名方法无法访问'this'的实例成员。任何人都可以解释这里发生了什么。通过引用捕获变量(即使它们实际上是值类型;然后进行装箱)。但是,ValueType(struct)中的this不能装箱,所以抓不到。EricLippert有一篇关于捕捉值类型惊喜的好文章。让我找到链接注意ChrisSinclair的评论:作为快速修复,您可以将结构存储在局部变量中:AthisA=this;varitems=Enumerable.Range(0,10).Where(i=>i==thisA._field);这个A=这个;varitems=Enumerable.Range(0,10).Where(i=>i==thisA._field);–ChrisSinclair4分钟前注意这会产生令人惊讶的情况:thisA的身份与this相同。更具体地说,如果您选择将lambda保留更长时间,它将有一个通过引用捕获的thisA的盒装副本,而不是被调用的SomeMethod的实际实例。当你有一个匿名方法时,它会被编译成一个新类,那个类将有一个方法(你定义的那个)。它还将引用您使用的每个在匿名方法范围之外的变量。重要的是要强调它是对该变量的引用,而不是副本。俗话说,“lambdas关闭变量,而不是值”。这意味着如果您关闭lambda范围之外的变量,然后在定义匿名方法之后(但在调用它之前)更改该变量,您将在调用它时看到更改后的值)。那么,这一切的意义何在?好吧,如果您要关闭一个结构(它是一个值类型),那么lambda可能会比结构长寿。匿名方法将在一个类中,而不是一个结构中,因此它将存在于堆中,只要它需要就可以存在,并且您可以自由地在任何地方(直接或间接)传递对该类的引用。现在假设我们有一个局部变量,其结构类型是您在此处定义的。我们使用这个命名方法生成一个lambda,让我们暂时假设查询项已返回(而不是方法无效)。然后,您可以将该查询存储在另一个实例(而不是本地)变量中,稍后在另一个方法中迭代该查询。会发生什么?本质上,一旦它不再在范围内,我们就会引用堆栈上的值类型。这意味着什么?答案是,我们不知道。(查看链接;这是我论点的症结所在。)数据可能碰巧是相同的,可能已被清零,也可能已填充了完全不同的对象,没有办法知道。作为一种语言,C#竭尽全力阻止您做这样的事情。像C或C++这样的语言并没有那么难阻止你拍自己的脚。现在,在这种特殊情况下,您可能不会在this引用范围之外使用lambda,但编译器不知道,如果它允许您创建lambda,它也无法确定它是否公开以一种会导致它被暴露的方式,所以防止这个问题的唯一方法是禁止某些实际上没有问题的情况。以上就是C#学习教程:为什么结构体中的匿名方法不能访问'this'的实例成员共享的所有内容。如果对大家有用,需要了解更多C#学习教程,希望大家多多关注——本文来自网络收藏,不代表立场,如涉及侵权,请点击有权联系管理员删除。如需转载请注明出处: