簡體   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