在此对象使用期限延长封一个C#编译器错误? [英] Is this object-lifetime-extending-closure a C# compiler bug?

查看:131
本文介绍了在此对象使用期限延长封一个C#编译器错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我回答问题了解倒闭的可能性(合法)延长对象的生命周期,当我遇到一些的非常的好奇代码生成的C#编译器(4.0,如果该事项)的一部分。

I was answering a question about the possibility of closures (legitimately) extending object-lifetimes when I ran into some extremely curious code-gen on the part of the C# compiler (4.0 if that matters).

我能找到最短的摄制如下:

The shortest repro I can find is the following:


  1. 创建一个lambda捕获本地,而调用的静态的包含类型的方法。

  2. 分配所产生的委托引用到的实例的领域。包含对象

  1. Create a lambda that captures a local while calling a static method of the containing type.
  2. Assign the generated delegate-reference to an instance field of the containing object.

结果:编译器创建一个闭合对象引用创建拉姆达的对象,当它没有理由到 - 委托的内在的目标是一个的静态的方法和λ-创建对象的实例成员不必是(并且不)执行委托时感动。实际上,编译器表现得像程序员已抓获这个没有道理的。

Result: The compiler creates a closure-object that references the object that created the lambda, when it has no reason to - the 'inner' target of the delegate is a static method, and the lambda-creating-object's instance members needn't be (and aren't) touched when the delegate is executed. Effectively, the compiler is acting like the programmer has captured this without reason.

class Foo
{
    private Action _field;

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

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

    private static void StaticMethod(double arg) { }
}

这是一个发布版本(反编译为'简单'C#)生成的代码如下:

The generated code from a release build (decompiled to 'simpler' C#) looks like this:

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 字段中填入对象引用,但从来没有从(没有理由)读

Observe that <>4__this field of the closure object is populated with an object reference but is never read from (there is no reason).

所以,这是怎么回事在这?请问语言规范允许吗?这是一个编译器错误/古怪或者是有一个很好的理由(即我清楚地丢失)的闭合来引用的对象?这让我着急,因为这看起来像是封闭开心程序员配方(像我)不知不觉引进奇怪的内存泄漏(想象一下,如果委托被用作事件处理程序)进入程序。

So what's going on here? Does the language-specification allow for it? Is this a compiler bug / oddity or is there a good reason (that I'm clearly missing) for the closure to reference the object? This makes me anxious because this looks like a recipe for closure-happy programmers (like me) to unwittingly introduce strange memory-leaks (imagine if the delegate were used as an event-handler) into programs.

推荐答案

这肯定看起来像一个bug。感谢它带给我的注意。我会考虑它。它是可能的,它已被发现并固定

That sure looks like a bug. Thanks for bringing it to my attention. I'll look into it. It is possible that it has already been found and fixed.

这篇关于在此对象使用期限延长封一个C#编译器错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆