2

什么反对使用委托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);
4

3 回答 3

6

好吧,您在那里提供的代码不是线程安全的 - 在您的 nullity test 和您的 call 之前,有人可能会取消订阅事件处理程序this.Disposing

但总的来说,它应该可以正常工作。不利的一面是,如果不遵守EventHandler约定,您可以订阅的内容会受到一些限制。

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

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

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

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

编辑:我刚刚记得其他一些库可能期望传统的事件签名 - 例如,Reactive Extensions 就可以。IIRC,订阅其他事件并非不可能,只是有点困难。

于 2011-05-24T09:03:33.360 回答
2

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

这样做的问题在于,您没有遵循事件的通用模式,其中委托是EventHandler<TEventArgs>,并且 TEventArgs 是包含事件参数的自定义类型。遵循这种模式的好处包括:

  • 代码可读性
  • 如果您需要向事件添加参数,则不必更改事件订阅者(因为您只需将其添加到自定义事件参数类中)。
于 2011-05-24T09:04:46.590 回答
1

一般来说:

Action用作事件处理程序没有问题。语言支持它,所以使用它:)

我能想到的唯一情况是尝试通过反射找到您的事件的代码。但是,如果该代码无法将任何委托作为事件类型处理,我会说他们的代码有问题,而不是你的。

你的具体例子:

您使用的模式的问题是您不应该在Dispose方法中真正使用该对象。有时它可能是安全的,但很容易出错。

例如,如果该Dispose方法在引发事件之前处置了资源,则该对象将处于不可用状态。

Dispose对于维护程序员来说,在编辑您的方法时,这可能很难(没有注释和强大的代码审查) 。

于 2011-05-24T09:05:59.483 回答