Mat*_*ero 5 .net c# lambda closures anonymous-function
假设我们有这个课程:
// Provides deferred behaviour
public class Command<TResult>
{
private Func<object[], TResult> _executeFunction;
private object[] _args;
public Command(Func<object[], TResult> execution, params object[] arguments)
{
_executeFunction = execution;
_args = arguments;
}
public TResult Execute()
{
return _executeFunction(_args);
}
}
Run Code Online (Sandbox Code Playgroud)
这两个匿名函数有什么区别?
int a = 1;
int b = 4;
// a and b are passed in as arguments to the function
Command<int> sum = new Command<int>(args => (int)args[0] + (int)args[1], a, b);
// a and b are captured by the function
Command<int> sum2 = new Command<int>(_ => a + b);
Console.WriteLine(sum.Execute()); //Prints out 5
Console.WriteLine(sum2.Execute()); //Prints out 5
Run Code Online (Sandbox Code Playgroud)
我特意寻找性能差异.
另外,我们知道,如果一些类举行的参考sum2,然后a和b会活过,他们就被定义范围,可能永远不会得到由GC收集函数是否依然任何地方引用.
是否会发生同样的事情sum?(考虑参数是引用类型而不是本示例中的值类型)
当您传入变量a和时b,您就是在这样做。1和的值4分别传入。但是,当您引用lambda 表达式的上下文(或范围)时,这些值将被“捕获” a。blambda 表达式范围内的变量a和b, 被视为对该范围之外的原始变量的引用,这意味着如果它们在 lambda 范围内发生更改,原始变量也会发生更改。当编译成 IL 时,它们驻留在共享实例的类中。
static void Main()
{
int a = 1;
int b = 4;
// a and b are passed in as arguments to the function
var sum = new Command<int>(args => (int)args[0] + (int)args[1], a, b);
// a and b are captured by the function
var sum2 = new Command<int>(_ =>
{
var c = a + b;
a++;
b++;
return c;
});
Console.WriteLine(sum.Execute()); //Prints out 5
Console.WriteLine(sum2.Execute()); //Prints out 5
Console.WriteLine("a = " + a); // Prints 2
Console.WriteLine("b = " + b); // Prints 5
Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)
IL 中的差异确实很小,而且我认为不存在任何值得避免其中之一的性能影响。我通常更喜欢使用 lambda 表达式,因为它们具有可读性。
| 归档时间: |
|
| 查看次数: |
102 次 |
| 最近记录: |