繁体   English   中英

Lambda闭包还是类级别变量?

[英]Lambda closure or class level variable?

关于最佳实践是一个普遍的问题:

public void Foo()
{
    int x = 5;
    myControl.Click += (o, e) =>
    {
        x = 6;
    };
}

注意,我在lambda事件处理程序中使用x变量。

要么:

public class Bar
{
    private int x = 5;
    public void Foo()
    {
        Control myControl = new Control();
        myControl.Click += new EventHandler(myControl_Click);
    }

    private void myControl_Click(object sender, EventArgs e)
    {
        x = 6;
    }
}

在此, x是该类的私有成员,因此我可以在事件处理程序中访问它。

现在让我们说我不需要在代码的其他任何地方使用x (无论出于何种原因),哪种方法是更好的选择?

这取决于您的需要。 在第一个示例中,事件处理程序的副作用仅限于方法范围,而在第二个示例中,副作用则在实例范围内。 我认为在第一个示例中使用闭包是没有用的,因为X并未在任何地方使用,因此很难根据示例来确定。

话虽如此,通常最好将事件处理程序(在代码中创建)与变量一样对待。 尽可能缩小范围,然后根据需要将它们重构为更大的范围。

突出显示何时使用闭包的更好示例如下:

public void Subscribe(Action<string> messageCallBack)
{
    myButton.Click += () => messageCallBack("Button was clicked.");
}

这允许多个订户,并且比替代方案要简单得多:

private readonly List<Action<string>> callBacks;
public MyClass()
{
    callBacks = new List<Action<string>>();
    myButton.Click += myButton_Click;
}

private myButton_Click(object sender, EventArgs e)
{
    foreach (Action<string> callBack in callBacks)
    {
        callBack("Button was clicked");
    }
}

public void Subscribe(Action<string> messageCallBack)
{
    callBacks.Add(messageCallBack);
}

如果您在代码中的其他任何地方都不需要x,则您的处理程序为空操作-因此,这肯定是胡扯。

一旦确实需要x,就需要确定它的作用域是Bar实例还是委托实例(或可能是某些委托集合),而这将决定您的工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM