2017-01-22 56 views
1

我想知道,如果我在下面的短代码片段中正确使用Lambda表达式?我想随时间存储函数调用,然后在Update_Calls()中一起执行它们。最重要的,我是问参数var1-3是否保留他们的价值在任何情况下(调用Extern_Func()当他们的价值)?如何在C#中正确使用lambda表达式的参数?

static List<Action> callsForUpdate = new List<Action>(); 

public static void Extern_Func(int var1, int var2, float var3) 
{ 
    Action callToStore =() => Func(var1, var2, var3); 

    // Remember in call list 
    callsForUpdate.Add(callToStore); 
} 

public static void Update_Calls() 
{ 
    for (int i = 0; i < callsForUpdate.Count; i++) 
    { 
    callsForUpdate.ElementAt(i); 
    } 

    callsForUpdate.Clear(); 
} 

回答

3

是的。他们将被保留。你的Update_Calls有问题。

public static void Update_Calls() 
    { 
     for (int i = 0; i < callsForUpdate.Count; i++) 
     { 
      callsForUpdate.ElementAt(i)(); 
     } 

     callsForUpdate.Clear(); 
    } 

你只是指的是元素。不叫它。

+0

非常感谢您指出这个问题!有趣的是,编译器不抱怨... –

+0

@ares_games为什么它应该抱怨? – InBetween

1

你所创建被称为封闭,这意味着Action将与var1, var2, var3当前值被调用,在这种情况下,他们的Extern_Func局部变量,所以除非你在该方法更改它们(Extern_Func)他们会保持自己的价值。

1

你所正在做的是创造一个表达的callsForUpdate列表中的每个项目指向。表达式是不可变的。为了更改您在表达式中提供的值,表达式必须由具有新值的新表达式替换。

在我最好的你所要求的估计,因为你的清单仅仅是为了与他们被Etern_Func创建时提供的值执行表达式的列表是最无论如何如此。

1

闭包捕获变量,不是值。确保清楚。

在你的情况下,var1,var2var3通过只能在本地更改的值参数传递。因此,如果你不在Extern_Func内部更换它们,你很好。

要了解捕捉值或变量之间的差异,考虑下面的代码片段:

var funcs = new List<Action>(); 

for (var i = 0; i < 5; i++) 
{ 
    var temp = i; 
    funcs.Add(() => Console.WriteLine(i)); 
    funcs.Add(() => Console.WriteLine(temp)); 
} 

foreach (var f in funcs) 
{ 
    f(); 
} 

你能猜到输出是什么?