C# 两种dispose实现之间的区别?

C# 两种dispose实现之间的区别?,c#,memory-leaks,delegates,event-handling,dispose,C#,Memory Leaks,Delegates,Event Handling,Dispose,这两种实现之间有区别吗 1: 公共类smsmsmanager:ManagerBase { 私有事件处理程序_按钮ClickEvent; 公共SMS管理员(数据块smsDataBlock、数据块电话SDatablock): 底座(smsDataBlock) { _ButtonClickeEvent=新事件处理程序(OnButtonClick); SheetEvents.ButtonClick+=\u ButtonClickeEvent; } 公共覆盖无效处置() { base.Dispose();

这两种实现之间有区别吗

1:

公共类smsmsmanager:ManagerBase
{
私有事件处理程序_按钮ClickEvent;
公共SMS管理员(数据块smsDataBlock、数据块电话SDatablock):
底座(smsDataBlock)
{
_ButtonClickeEvent=新事件处理程序(OnButtonClick);
SheetEvents.ButtonClick+=\u ButtonClickeEvent;
}
公共覆盖无效处置()
{
base.Dispose();
如果(_buttonClickevent!=null)
SheetEvents.ButtonClick-=\u按钮ClickEvent;
}
}
2:

公共类smsmsmanager:ManagerBase
{
公共SMS管理员(数据块smsDataBlock、数据块电话SDatablock):
底座(smsDataBlock)
{
SheetEvents.ButtonClick+=新事件处理程序(OnButtonClick);
}
公共覆盖无效处置()
{
base.Dispose();
SheetEvents.ButtonClick-=新事件处理程序(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;

@SwDevMan81宾果!助教,我一直在寻找这些信息。这就是为什么我们都在这里闲逛:)总是学习新知识things@All有趣的一个是带有匿名方法的事件处理程序(新时尚),它们不能很好地发挥作用。我是前几天才知道的。@SwDevMan81在这个网站上学习新事物的唯一问题是,需要花时间检查旧代码(或昨天编写的代码),看看你是否犯了当时不知道的错误。哈哈!发生这种事的次数…@亚当-哈哈,真的。我有666个答案,所以我让邪恶的旧代码继续存在:别忘了把答案标记为答案,它有助于丰富这个网站的内容。
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);
        }
    }
}
Func<object, EventArgs> meth = (s, e) => DoSomething();

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

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