lambda 每次被调用时都会创建一个新实例吗?

发布于 2024-07-27 23:04:00 字数 304 浏览 2 评论 0原文

我很好奇 Lambda(用作委托时)是否会在每次调用时创建一个新实例,或者编译器是否会找到一种方法来仅实例化委托一次并传入该实例。

更具体地说,我想为 XNA 游戏创建一个 API,我可以使用 lambda 来传递自定义回调。 由于这将在 Update 方法中调用(每秒调用多次),如果每次都更新一个实例来传入委托,那将是非常糟糕的。

InputManager.GamePads.ButtonPressed(Buttons.A, s => s.MoveToScreen<NextScreen>());

I'm curious to know whether a Lambda (when used as delegate) will create a new instance every time it is invoked, or whether the compiler will figure out a way to instantiate the delegate only once and pass in that instance.

More specifically, I'm wanting to create an API for an XNA game that I can use a lambda to pass in a custom call back. Since this will be called in the Update method (which is called many times per second) it would be pretty bad if it newed up an instance everytime to pass in the delegate.

InputManager.GamePads.ButtonPressed(Buttons.A, s => s.MoveToScreen<NextScreen>());

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

您的好友蓝忘机已上羡 2024-08-03 23:04:00

是的,它会在可能的情况下缓存它们:

using System;

class Program {
    static void Main(string[] args) {
        var i1 = test(10);
        var i2 = test(20);
        System.Console.WriteLine(object.ReferenceEquals(i1, i2));
    }

    static Func<int, int> test(int x) {
        Func<int, int> inc = y => y + 1;
        Console.WriteLine(inc(x));
        return inc;
    }
}

它创建一个静态字段,如果它为空,则用新的委托填充它,否则返回现有的委托。

输出 10、20、true。

Yes, it will cache them when it can:

using System;

class Program {
    static void Main(string[] args) {
        var i1 = test(10);
        var i2 = test(20);
        System.Console.WriteLine(object.ReferenceEquals(i1, i2));
    }

    static Func<int, int> test(int x) {
        Func<int, int> inc = y => y + 1;
        Console.WriteLine(inc(x));
        return inc;
    }
}

It creates a static field, and if it's null, populates it with a new delegate, otherwise returns the existing delegate.

Outputs 10, 20, true.

旧情别恋 2024-08-03 23:04:00

我对你的问题很感兴趣,因为我刚刚假设这种事情总是会生成一个新对象,因此在经常调用的代码中要避免。

我做了类似的事情,所以我想我应该使用 ildasm 来找出幕后到底发生了什么。 就我而言,事实证明,每次调用委托时都会创建一个新对象,我不会发布我的代码,因为它相当复杂,并且在脱离上下文的情况下不太容易理解。 这与 MichaelGG 提供的答案相冲突,我怀疑是因为在他的示例中他使用了静态函数。 我建议您先亲自尝试一下,然后再以一种方式设计所有内容,然后再发现存在问题。 ildasm 是要走的路 (http://msdn.microsoft.com/en -us/library/f7dy01k1.aspx),留意任何“newobj”行,你不需要这些。

还值得使用 CLR Profile 来查明您的 lambda 函数是否正在分配内存 (https://github.com/MicrosoftArchive/ clrprofiler)。 它说它适用于框架 2.0,但它也适用于 3.5,并且它是可用的最新版本。

I was interested by your question because I had just assumed that this kind of thing would always generate a new object and hence to be avoided in code which is called frequently.

I do something similar so I thought I would use ildasm to find out what exactly is going on behind the scenes. In my case it turned out that a new object was getting created each time the delegate was called, I won't post my code because it is fairly complex and not very easy to understand out of context. This conflicts with the answer provided by MichaelGG, I suspect because in his example he makes use of static functions. I would suggest you try it for yourself before designing everything one way and later on finding out that you have a problem. ildasm is the way to go (http://msdn.microsoft.com/en-us/library/f7dy01k1.aspx), look out for any "newobj" lines, you don't want those.

Also worth using CLR Profile to find out if your lambda functions are allocating memory (https://github.com/MicrosoftArchive/clrprofiler). It says it's for framework 2.0 but it also works for 3.5 and it's the latest version that is available.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文