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

时间:2009-07-16 02:39:30

标签: c# lambda xna garbage-collection

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

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

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

2 个答案:

答案 0 :(得分:3)

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

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;
    }
}

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

输出10,20,真。

答案 1 :(得分:3)

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

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

还值得使用CLR Profile来查明lambda函数是否正在分配内存(http://www.microsoft.com/downloads/details.aspx?familyid=A362781C-3870-43BE-8926-862B40AA0CD0&displaylang=en)。它说它适用于框架2.0,但它也适用于3.5,它是最新版本。