2015-01-14 149 views
0

内架空委托定义的我很好奇,想知道发生了什么幕后在这样的情况:另一种方法

public static void OuterMethod() { 
    // some random code 
    var a = 42; 
    var b = "meaning of life";   

    Func<string, object> factory = (aString) { 
     // do something with a and b 
     return "Hello World"; 
    }; 

    // some more random code 
    factory("My string"); 
} 

我在OuterMethod被称为非常频繁的情况下特别感兴趣。在我的情况下,这是MVC请求管道,其中OuterMethod为每个请求调用一次。

我每次调用该方法时都必须构建factory,从而导致大量开销?我可以很容易地将OuterMethod以外的Func移动到它自己的静态方法中,但是在我的实际场景中,因为它是在里面定义的,我可以访问很多变量,我需要做我的计算,否则我需要在签名中包含方法在外面定义。也许这只是一个微型优化,但我想更好地理解编译器如何处理这些类型的语句。

+1

Servy的答案是正确的,您将在每次调用OuterMethod时创建一个委托的新参考。然而,从设计的角度来看,这可能会违反单一的责任原则。 OuterMethod负责构建对象(或者执行计算),并负责OuterMethod的真实工作。因此,以自己的方法进行工厂/计算会更可取。当然,如果您只是使用OuterMethod为代理创建一个状态环境,那就没问题。 –

回答

2

实际的lambda会导致在编译时创建一个新的命名方法(您只是不知道该名称是什么)(确切的语义会根据一些具体情况而有所不同)。

对每个方法调用所做的唯一工作是创建一个新的委托对象,该委托对象具有自己的指向同一个命名方法的指针。如果构建一个对象实例的确很难(提示:不是),那么可以通过从方法中提取委托来保存该工作。

+0

谢谢!始终感谢您的洞察力。我有一种感觉,它会在编译时以某种方式照顾我,但只是想确定:) –