gpt4 book ai didi

c# - 这个 object-lifetime-extending-closure 是 C# 编译器错误吗?

转载 作者:IT王子 更新时间:2023-10-29 03:32:40 24 4
gpt4 key购买 nike

我正在回答 question关于闭包(合法地)延长对象生命周期的可能性,当我遇到一些非常好奇的 C# 编译器代码生成(如果重要的话是 4.0)。

我能找到的最短的重现如下:

  1. 创建一个在调用包含类型的static 方法时捕获本地的 lambda。
  2. 将生成的委托(delegate)引用分配给包含对象的实例字段。

结果:编译器创建一个引用创建 lambda 的对象的闭包对象,但它没有理由这样做 - 委托(delegate)的“内部”目标是一个静态方法,并且执行委托(delegate)时,不需要(也不会)触及 lambda-creating-object 的实例成员。实际上,编译器就像程序员捕获了 this 一样。没有理由。

class Foo
{
private Action _field;

public void InstanceMethod()
{
var capturedVariable = Math.Pow(42, 1);

_field = () => StaticMethod(capturedVariable);
}

private static void StaticMethod(double arg) { }
}

发布版本生成的代码(反编译为“更简单的”C#)如下所示:

public void InstanceMethod()
{

<>c__DisplayClass1 CS$<>8__locals2 = new <>c__DisplayClass1();

CS$<>8__locals2.<>4__this = this; // What's this doing here?

CS$<>8__locals2.capturedVariable = Math.Pow(42.0, 1.0);
this._field = new Action(CS$<>8__locals2.<InstanceMethod>b__0);
}

[CompilerGenerated]
private sealed class <>c__DisplayClass1
{
// Fields
public Foo <>4__this; // Never read, only written to.
public double capturedVariable;

// Methods
public void <InstanceMethod>b__0()
{
Foo.StaticMethod(this.capturedVariable);
}
}

观察 <>4__this闭包对象的字段填充了一个对象引用,但从未被读取(没有原因)。

那么这里发生了什么?语言规范允许吗?这是一个编译器错误/奇怪还是有一个很好的理由(我显然没有)让闭包引用该对象?这让我很焦虑,因为这看起来像是喜欢闭包的程序员(比如我)无意中将奇怪的内存泄漏(想象一下如果委托(delegate)被用作事件处理程序)引入程序的秘诀。

最佳答案

这确实看起来像一个错误。谢谢你让我注意到它。我会调查一下。可能已经找到并修复了。

关于c# - 这个 object-lifetime-extending-closure 是 C# 编译器错误吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8419079/

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