在处理方法中删除委托成员时可以使用等于赋值吗?
Can you use equals assignment when removing delegate members in a disposing method?
我的 class
中有以下代码
public class Receiver : IReceiver
{
public event EventHandler Received;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (Received != null)
{
foreach (EventHandler delegateMember in Received.GetInvocationList())
{
Received -= delegateMember;
}
}
}
}
}
这段代码的工作原理是,当我处理我的 class 任何连接到 Received 事件的事件时,都将被单独删除。
我一直在想,与其说得那么冗长,不如说下面的简洁版本是否会产生同样的效果
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
Received = null;
}
}
基本上这归结为 Microsoft 在实现委托重载时如何创建运算符重载。我知道所有文档都说使用 += 订阅和 -= 取消订阅事件。我还看到文档说,当最后一个订阅者被删除时,事件将被分配为空。文档没有说的是,将事件赋值为null,是否会起到取消订阅所有事件的效果?
我很想知道这是否可行,以及是否有任何文档表明可能的简洁代码是正确的行为。
更新:
我一直在使用 c# 编译器进行更多挖掘,发现对 null 的赋值仅在定义事件的 class 中有效。 += 和 -= 在 class 的内部和外部始终可用。这让我想到使用 = null 版本是可以接受的。然而,这只是猜测,我还没有看到任何文档明确说明这是受支持的功能。
没有理由不在这里将 null
分配给委托人。
如果您不在定义事件的 class 范围内,您将无法 能够 分配 null
。对于使用 class 的任何人来说,他们应该只关心自己的处理程序,他们可以添加或删除这些处理程序。他们无法访问其他人的处理程序。
您需要记住委托是不可变的。在事件上使用 +=
不会改变委托以向该委托添加新方法,它会创建一个新委托,在调用时会调用添加在一起的两个委托。使用 -=
创建一个委托,调用除第二个操作数之外的第一个操作数的所有调用。因此,一遍又一遍地调用 -=
会不断创建越来越多的委托,每个委托调用的东西越来越少,直到最终您到达委托不再调用任何东西的地步。仅分配 null
相当于仅创建一个不执行任何操作的委托,然后直接分配它。
因此,当您一遍又一遍地调用 -=
时,在您开始之前分配给该事件的原始委托仍然存在,还有 N 个中间委托。也就是说,none 的委托可能会被任何根元素引用,因此它们都符合收集条件。如果你只是分配 null
你仍然有原来在那里的那个孤立的代表,你只是不再有任何中间代表了。
我的 class
中有以下代码public class Receiver : IReceiver
{
public event EventHandler Received;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (Received != null)
{
foreach (EventHandler delegateMember in Received.GetInvocationList())
{
Received -= delegateMember;
}
}
}
}
}
这段代码的工作原理是,当我处理我的 class 任何连接到 Received 事件的事件时,都将被单独删除。
我一直在想,与其说得那么冗长,不如说下面的简洁版本是否会产生同样的效果
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
Received = null;
}
}
基本上这归结为 Microsoft 在实现委托重载时如何创建运算符重载。我知道所有文档都说使用 += 订阅和 -= 取消订阅事件。我还看到文档说,当最后一个订阅者被删除时,事件将被分配为空。文档没有说的是,将事件赋值为null,是否会起到取消订阅所有事件的效果?
我很想知道这是否可行,以及是否有任何文档表明可能的简洁代码是正确的行为。
更新:
我一直在使用 c# 编译器进行更多挖掘,发现对 null 的赋值仅在定义事件的 class 中有效。 += 和 -= 在 class 的内部和外部始终可用。这让我想到使用 = null 版本是可以接受的。然而,这只是猜测,我还没有看到任何文档明确说明这是受支持的功能。
没有理由不在这里将 null
分配给委托人。
如果您不在定义事件的 class 范围内,您将无法 能够 分配 null
。对于使用 class 的任何人来说,他们应该只关心自己的处理程序,他们可以添加或删除这些处理程序。他们无法访问其他人的处理程序。
您需要记住委托是不可变的。在事件上使用 +=
不会改变委托以向该委托添加新方法,它会创建一个新委托,在调用时会调用添加在一起的两个委托。使用 -=
创建一个委托,调用除第二个操作数之外的第一个操作数的所有调用。因此,一遍又一遍地调用 -=
会不断创建越来越多的委托,每个委托调用的东西越来越少,直到最终您到达委托不再调用任何东西的地步。仅分配 null
相当于仅创建一个不执行任何操作的委托,然后直接分配它。
因此,当您一遍又一遍地调用 -=
时,在您开始之前分配给该事件的原始委托仍然存在,还有 N 个中间委托。也就是说,none 的委托可能会被任何根元素引用,因此它们都符合收集条件。如果你只是分配 null
你仍然有原来在那里的那个孤立的代表,你只是不再有任何中间代表了。