2

只是关于最佳实践是什么的一般问题:

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

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

或者:

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代码中的其他任何地方(无论出于何种原因),哪种方法更好?

4

2 回答 2

3

这取决于您的需要。在第一个示例中,事件处理程序的副作用仅限于方法范围,而在第二个示例中,副作用仅限于实例范围。我认为在您的第一个示例中使用闭包没有任何意义,因为 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);
}
于 2009-01-08T15:55:21.867 回答
1

如果您在代码中的其他任何地方都不需要 x,则您的处理程序是无操作的 - 所以这肯定是一种无意义的情况。

一旦你确实需要 x,你需要决定它的范围是 Bar 实例还是委托实例(或者可能是一些委托的集合),这将决定你做什么。

于 2009-01-08T15:52:44.447 回答