参加以下C#课程:
c1 {
event EventHandler someEvent;
}
Run Code Online (Sandbox Code Playgroud)
如果有很多订阅c1的someEvent事件,我想清除所有这些,那么实现这一目标的最佳方法是什么?还要考虑对此事件的订阅可以是lambdas/anonymous delegates.
目前我的解决方案是添加一个ResetSubscriptions()方法,将c1其设置someEvent为null.我不知道这是否有任何看不见的后果.
让我们说我们有一个代表
public delegate void MyEventHandler(string x);
Run Code Online (Sandbox Code Playgroud)
和一个事件处理程序
public event MyEventHandler Something;
Run Code Online (Sandbox Code Playgroud)
我们添加了多个事件..
for(int x = 0; x <10; x++)
{
this.Something += HandleSomething;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是..如何从事件处理程序中删除所有方法,假设一个人不知道它已被添加10(或更多或更少)次?
我有点新,c#所以如果你觉得它很琐碎,请忽略.我看到了以下"奇怪"的代码.
任何人都可以对此有所了解.
public event Action _action;
if (_action != null)
{
foreach (Action c in _action.GetInvocationList())
{
_action -= c;
}
}
Run Code Online (Sandbox Code Playgroud)
特别是_action -= c;部分.
假设我有一个 C# 类,如下所示:
public class MyClass {
public SomeObject TheObject { get; }
public MyClass() {
TheObject = new SomeObject();
TheObject.MyEvent += MyEventHandler;
}
private void MyEventHandler() {
// some code
}
}
Run Code Online (Sandbox Code Playgroud)
该类创建一个名为 TheObject 的 SomeObject 类型的内部对象,并向该对象上的事件添加一个事件处理程序。
由于 TheObject 是一个公共属性,这意味着任何其他代码段都可以维护指向该对象的指针;反过来,这将使 MyClass 类型的对象保持活动状态,因为 TheObject 有一个以事件处理程序形式指向 MyClass 的指针。
因此,我认为保持此代码不受此事件影响的唯一方法是向 MyClass 添加终结器:
public ~MyClass() {
TheObject?.MyEvent -= MyEventHandler;
}
Run Code Online (Sandbox Code Playgroud)
这太糟糕了,因为终结器会将 MyClass 类型的对象提升到下一代 GC,但我是否正确地认为这是避免这种潜在内存泄漏的唯一方法?