参加以下C#课程:

c1 {
 event EventHandler someEvent;
}

如果对 c1 someEvent 事件有很多订阅,我想清除它们,那么实现这一目标的最佳方法是什么? 另请注意,此活动的订阅可能是lambdas /匿名代表。

目前我的解决方案是将 ResetSubscriptions()方法添加到 c1 ,将 someEvent 设置为null。我不知道这是否有任何看不见的后果。

有帮助吗?

解决方案

在类中,您可以将(hidden)变量设置为null。空引用是有效地表示空调用列表的规范方式。

从课外,你不能这样做 - 事件基本上暴露了“订阅”。和“取消订阅”就是这样。

值得注意的是,类似字段的事件实际上是在做什么 - 他们同时创建了一个变量一个事件。在类中,您最终引用变量。从外面,你可以参考这个活动。

有关详细信息,请参阅我的有关活动和代表的文章

其他提示

向c1添加一个方法,将'someEvent'设置为null ...

class c1
{
    event EventHandler someEvent;
    ResetSubscriptions() {someEvent = null;}
}
class c1
{
    event EventHandler someEvent;
    ResetSubscriptions() {someEvent = delegate{};}
}

最好使用委托{}而不是

在类中将事件设置为null有效。当你处理一个类时,你应该总是将事件设置为null,GC有事件问题,如果它有悬空事件,可能不会清理已处理的类。

清除所有订阅者的最佳做法是,如果要将此功能公开给外部,可以通过添加另一个公共方法将someEvent设置为null。这没有任何看不见的后果。前提条件是记住使用关键字“event”声明SomeEvent。

请参阅书籍 - 简言之C#4.0,第125页。

这里有人建议使用 Delegate.RemoveAll 方法。如果您使用它,示例代码可以遵循以下形式。但这真的很愚蠢。为什么不在 ClearSubscribers()函数中 SomeEvent = null

   public void ClearSubscribers ()
    {
          SomeEvent = (EventHandler) Delegate.RemoveAll(SomeEvent, SomeEvent);// Then you will find SomeEvent is set to null.
    }

您可以使用Delegate.Remove或Delegate.RemoveAll方法来实现此目的。

概念扩展无聊评论。

我宁愿使用“事件处理程序”这个词。而不是“事件”或“委托”。并使用了“事件”一词。其他的东西。在一些编程语言(VB.NET,Object Pascal,Objective-C)中,“事件”是一种编程语言。被称为“消息”或“信号”,甚至具有“消息”或“消息”。关键字和特定的糖语法。

const
  WM_Paint = 998;  // <-- "question" can be done by several talkers
  WM_Clear = 546;

type
  MyWindowClass = class(Window)
    procedure NotEventHandlerMethod_1;
    procedure NotEventHandlerMethod_17;

    procedure DoPaintEventHandler; message WM_Paint; // <-- "answer" by this listener
    procedure DoClearEventHandler; message WM_Clear;
  end;

并且,为了响应该“消息”,“事件处理程序”也是如此。回答,无论是单个代表还是多个代表。

要点: &QUOT;事件&QUOT;是“问题”,“事件处理程序”是“问题”。是答案。

这是我的解决方案:

public class Foo : IDisposable
{
    private event EventHandler _statusChanged;
    public event EventHandler StatusChanged
    {
        add
        {
            _statusChanged += value;
        }
        remove
        {
            _statusChanged -= value;
        }
    }

    public void Dispose()
    {
        _statusChanged = null;
    }
}

您需要调用 Dispose()或使用使用(new Foo()){/*...*/} 模式取消订阅调用列表的所有成员

删除所有事件,假设事件是“行动”。类型:

Delegate[] dary = TermCheckScore.GetInvocationList();

if ( dary != null )
{
    foreach ( Delegate del in dary )
    {
        TermCheckScore -= ( Action ) del;
    }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top