系统.Action作为事件处理程序
反对使用委托 System.Action
或 System.Func
作为 EventDelegates 而不是经典的 EventHandler
模式。我会因此遇到问题吗?
private bool disposed;
public event Action<IUnitOfWork, IContext> Disposing;
public void Dispose()
{
if (this.disposed)
{
return;
}
if (null != this.Disposing)
{
this.Disposing(this, this.AttachedContext);
}
this.disposed = true;
}
用法:
unitOfWorkInstance.Disposing += (u, c) => c.Rollback(u); // in my opinion more readable than
unitOfWorkInstance.Disposing += (sender, args) => args.AttachedContext.Rollback(sender as IUnitOfWork);
What speaks against using the delegates System.Action
or System.Func
as EventDelegates instead of the classic EventHandler
pattern. Will I therefore run into problems?
private bool disposed;
public event Action<IUnitOfWork, IContext> Disposing;
public void Dispose()
{
if (this.disposed)
{
return;
}
if (null != this.Disposing)
{
this.Disposing(this, this.AttachedContext);
}
this.disposed = true;
}
Usage:
unitOfWorkInstance.Disposing += (u, c) => c.Rollback(u); // in my opinion more readable than
unitOfWorkInstance.Disposing += (sender, args) => args.AttachedContext.Rollback(sender as IUnitOfWork);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
好吧,您提供的代码不是线程安全的 - 在您的无效测试之后和调用
this.Dispose
之前,有人可能会取消订阅事件处理程序。但总的来说,它应该工作得很好。缺点是,如果不遵循
EventHandler
约定,您在可以订阅的内容方面会受到更多限制。例如,假设您有一个非常通用的事件处理程序方法:
您可以使用它来订阅遵循正常约定的任何事件 - 但不能使用
你的活动。
但这是一个相当小的缺点。我想一个可能更大的问题是,它可能会让其他希望看到传统事件签名的开发人员感到困惑。
编辑:我刚刚记得其他一些库可能需要传统的事件签名 - 例如,反应性扩展就是如此。 IIRC,订阅其他活动也不是不可能,只是有点难。
Well, the code you've given there isn't thread-safe - someone could unsubscribe from the eventhandler after your nullity test and before your call
this.Disposing
.But in general, it should work just fine. The downside is that by not following the
EventHandler
convention, you're slightly more limited in terms of what can subscribe.For example, suppose you have a very general event handler method:
You can use this to subscribe to any event following the normal convention - but not with
your event.
This is a pretty minor downside though. I guess a potentially bigger one is that it may confuse other developers who are expecting to see a conventional event signature.
EDIT: I've just remembered that some other libraries may expect the conventional event signature - Reactive Extensions does, for example. IIRC, it's not impossible to subscribe to other events, just a bit harder.
从“代码是否有效”的角度来看,我想说将这些委托类型用于事件是完全可以的。
这样做的问题是,您没有遵循事件的常见模式,其中委托是
EventHandler
,而 TEventArgs 是包含事件参数的自定义类型。遵循此模式的好处包括:From a "does-the-code-work" perspective, I would say it is perfectly OK to use these delegate types for events.
The problem with doing this, is that you are not following the common pattern for events, where the delegate is
EventHandler<TEventArgs>
, and TEventArgs is a custom type that contains the parameters for the event. The benefits of following this pattern include:一般情况:
使用
Action
作为事件处理程序没有问题。它受语言支持,因此请使用它:)我能想到的唯一情况是尝试通过反射查找事件的代码。但是,如果该代码无法将任何委托作为事件类型处理,我会说他们的代码有问题,而不是你的。
您的具体示例:
您使用的模式的问题是您不应该在
Dispose
方法中真正使用该对象。有时它可能是安全的,但很容易出错。例如,如果
Dispose
方法在引发事件之前处置资源,则该对象将处于不可用状态。对于维护程序员来说,在编辑
Dispose
方法时很难做到这一点(没有注释和强有力的代码审查)。In general:
There is no problem with using
Action
as your event handler. It is supported by the language, so use it :)The only case I can think of is code that tries to find your events via reflections. But if that code couldn't handle any delegate as an event type, I'd say their code was buggy, not yours.
Your specific example:
The problem with the pattern you are using is that you shouldn't really be using the object while in the
Dispose
method. It could be safe sometimes, but would be easy to get wrong.For example, if the
Dispose
method disposed resources before raising the event, then the object would be in an unusable state.This could be hard (without comments and strong code reviews) for a maintenance programmer to get right when editing your
Dispose
method.