我有一个模型类,其中包含我从其他类订阅的事件。我想在每个类中正确订阅和取消订阅。
其次除MyClass之外还有其他类使用OnMyEvent,因此我不想无意中取消订阅该类中的事件。
MyClass(IModel model)
{
_model = model;
_model.OnMyEvent +=EventHandle;
}
Close()
{
_model.OnMyEvent -=EventHandle;
}
Disconnect()
{
//I want to check if OnMyEvent has already unsibscribed
//Moreover OnMyEvent is used in other classes and
//I don't want to mess up with it here
_model.OnMyEvent -=EventHandle;
}
答案 0 :(得分:11)
如果您只订阅一次,那么 多次取消订阅并不重要 - 当您没有订阅时取消订阅是无操作。同样,事件API的重点是不能意外取消订阅其他订阅(其他类型或其他相同类型的实例)。
因此,显示的代码应该没问题,尽管将两个调用移动到处理此问题的单个方法可能是值得的。但这可能有点矫枉过正。
此外,如果您的类型为IDisposable
,请确保在该代码路径中调用它(可能是通过调用Close()
)。
答案 1 :(得分:2)
您可以安全地从事件中多次取消订阅相同的处理程序。不需要额外的检查,这将是反作用的。
答案 2 :(得分:1)
如果您想保证只取消订阅一次,可以使用GetInvocationList
方法:
if (_model.OnMyEvent != null && _model.GetInvocationList().Contains(EventHandle))
{
_model.OnMyEvent -= EventHandle
}
但正如其他人所说,您可以多次取消订阅。如果这确实不是问题,请保持这种状态。我提出的解决方案只是代码噪声。只需在一行中取消订阅就更简洁,当您的课程开始成长时更容易阅读。
答案 3 :(得分:1)
您还可以使用此声明控制订阅和取消订阅。但是你还必须遍历字典并调用手动订阅的代理。
private Dictionary<string, EventHandler> TestEvents { get; }
public event EventHandler TestEvent
{
add
{
string name = value.GetType().FullName;
if (!TestEvents.ContainsKey(name))
{
TestEvents.Add(name, value);
}
}
remove
{
string name = value.GetType().FullName;
if (TestEvents.ContainsKey(name))
{
TestEvents.Remove(name);
}
}
}