当作为委托传递时,是否应在lambda语句中使用局部变量?

时间:2017-03-28 09:46:32

标签: c# lambda delegates

如果我的方法采用Action类型的参数,例如:

public void Foo(Action bar)
{
    bar?.Invoke();
}

我希望传递一个使用局部变量的lambda,例如:

private void SomeEvent(object sender, SomeEventArgs e)
{
    foo(() => { e.Cancel = true; });
}

对于本地变量的使用,这个lambda是否会按预期执行,在本例中为e?我的意思是,当foo()被调用并反过来试图调用lambda时,它会知道e吗?或e是否超出范围,我应该做以下的事情?

private void SomeEvent(object sender, SomeEventArgs e)
{
    foo((SomeEventArgs a) => { a.Cancel = true; }, e);
}

public void Foo(Action<SomEventArgs> bar, SomeEventArgs e)
{
    bar?.Invoke(e);
}

2 个答案:

答案 0 :(得分:3)

这个小例子表明局部变量将被改变:

void Main()
{
    int local = 0;

    Foo(() => { local = 55; });
    Console.WriteLine(local);
}

public static void Foo(Action bar)
{
    bar?.Invoke();
}

输出:

  

55

此示例还可以扩展为包含事件:

public class P
{
    public delegate void MyEventDelegate(bool e);

    public event MyEventDelegate MyEvent;

    public void shootEvent() {MyEvent(false);}
}

void Main()
{       
    P p = new P();
    p.MyEvent += MyeventHandler;

    p.shootEvent();
}

public void MyeventHandler(bool b)
{
    Foo(() => { b = true; });
    Console.WriteLine(b);
}

输出:

  

答案 1 :(得分:2)

是的,它应该按预期工作。这被称为&#34;变量捕获&#34;,并且很好地解释了here

在您的示例中,捕获了e变量,因此它不会超出范围。

相关问题