两个dispose实现之间的区别?

这两个实现有什么区别吗?

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);
        }
    }
}

此示例打印“已处理”一次。

因此,在您的示例中,它们在功能上是相同的,都将根据需要进行工作。 删除尚未添加的处理程序也是安全的操作,它只是找不到任何要删除的内容,并且什么也不做。

正如评论中所提供的那样,Marc的答案更为详细:

使用委托的新实例取消注册事件


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

值得注意的是,以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();
    }
}
链接地址: http://www.djcxy.com/p/51453.html

上一篇: Difference between two dispose implementations?

下一篇: Events with lambda expression