系统.Action作为事件处理程序

发布于 2024-11-09 12:38:20 字数 685 浏览 0 评论 0原文

反对使用委托 System.ActionSystem.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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

李不 2024-11-16 12:38:20

好吧,您提供的代码不是线程安全的 - 在您的无效测试之后和调用 this.Dispose 之前,有人可能会取消订阅事件处理程序。

但总的来说,它应该工作得很好。缺点是,如果不遵循 EventHandler 约定,您在可以订阅的内容方面会受到更多限制。

例如,假设您有一个非常通用的事件处理程序方法:

public void LogEvent(object sender, EventArgs e)
{
    Console.WriteLine("Event raised");
}

您可以使用它来订阅遵循正常约定的任何事件 - 但不能使用
你的活动。

但这是一个相当小的缺点。我想一个可能更大的问题是,它可能会让其他希望看到传统事件签名的开发人员感到困惑。

编辑:我刚刚记得其他一些库可能需要传统的事件签名 - 例如,反应性扩展就是如此。 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:

public void LogEvent(object sender, EventArgs e)
{
    Console.WriteLine("Event raised");
}

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.

嘿哥们儿 2024-11-16 12:38:20

从“代码是否有效”的角度来看,我想说将这些委托类型用于事件是完全可以的。

这样做的问题是,您没有遵循事件的常见模式,其中委托是 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:

  • Code readability
  • Not having to change event subscribers if you need to add a parameter to the events (because you will just add it to your custom event arguments class).
最舍不得你 2024-11-16 12:38:20

一般情况:

使用 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文