簡體   English   中英

兩個Dispose實現之間的區別?

[英]Difference between two dispose implementations?

這兩種實現之間有區別嗎?

1:

public class SMSManager : ManagerBase
{
    private EventHandler<SheetButtonClickEventArgs> _buttonClickevent; 

    public SMSManager(DataBlock smsDataBlock, DataBlock telephonesDataBlock) :
        base(smsDataBlock)
    {
        _buttonClickevent = new EventHandler<SheetButtonClickEventArgs>(OnButtonClick);
        SheetEvents.ButtonClick += _buttonClickevent;

    }

    public override void Dispose()
    {
        base.Dispose();
        if (_buttonClickevent != null)
        SheetEvents.ButtonClick -= _buttonClickevent;
    }
}

2:

public class SMSManager : ManagerBase
{
    public SMSManager(DataBlock smsDataBlock, DataBlock telephonesDataBlock) :
        base(smsDataBlock)
    {
        SheetEvents.ButtonClick += new EventHandler<SheetButtonClickEventArgs>(OnButtonClick);   
    }

    public override void Dispose()
    {
        base.Dispose();
        SheetEvents.ButtonClick -= new EventHandler<SheetButtonClickEventArgs>(OnButtonClick);
    }
}

關於內存泄漏,第一個似乎比第二個更正確。 但這真的正確嗎?

它的長短是第二段代碼正確且安全(即使沒有注冊處理程序)。

考慮以下示例應用程序:

namespace ConsoleApplication61
{
    class Program
    {
        static void Main(string[] args)
        {
            var f = new Foo();
            f.MyEvent += new EventHandler(Handler);
            f.Trigger();
            f.MyEvent -= new EventHandler(Handler);
            f.Trigger();
            Console.Read();
        }

        static void Handler(object sender, EventArgs e)
        {
            Console.WriteLine("handled");
        }
    }

    class Foo
    {
        public event EventHandler MyEvent;
        public void Trigger()
        {
            if (MyEvent != null)
                MyEvent(null, null);
        }
    }
}

此樣本僅打印一次“已處理”。

因此,在您的示例中,它們在功能上相同,並且都可以根據需要工作。 刪除未添加的處理程序也是安全的操作,它只是發現沒有要刪除的內容,也不執行任何操作。

正如評論中所提供的,馬克的答案更加詳細:

使用委托的新實例注銷事件


具有匿名方法的事件處理程序

值得注意的是,不能保證lambda表達式形式的事件處理程序根據實例和方法簽名強制執行唯一性。 如果您需要取消訂閱匿名方法,則需要將其升級為方法或保留對匿名方法的引用以供以后使用:

Func<object, EventArgs> meth = (s, e) => DoSomething();

myEvent += meth;
myEvent -= meth;

喬恩·斯凱特(Jon Skeet)詳細回答了這一問題,它可能比我做得更好:-)

如何刪除Lambda事件處理程序


輕微重構

我將重構為以下內容:

public class SMSManager : ManagerBase
{
    public SMSManager(DataBlock smsDataBlock, DataBlock telephonesDataBlock) 
        : base(smsDataBlock)
    {
        SheetEvents.ButtonClick += OnButtonClick;   
    }

    public override void Dispose()
    {
        SheetEvents.ButtonClick -= OnButtonClick;
        base.Dispose();
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM