即使只有一个动作参数就足够了,也要使用事件吗?
Use events even if just an action parameter would be sufficient?
在我的场景中,我有一个 class 会时不时地为我做一些工作,偶尔会对它做出一些反应。实际操作是什么将由外部提供。我认为值得一提的是,只有 一个 外部实例告诉这个 class 必须做什么。
我已经实现了这样的东西:
public class DelegatePublisher
{
private Action<byte[], int, int> onCompleted;
public DelegatePublisher(Action<byte[], int, int> onCompleted)
{
this.onCompleted = onCompleted;
}
public void Invoke(byte[] buffer, int index, int count)
{
onCompleted.Invoke(buffer, index, count);
}
}
这可以在以后简单地使用:
public class Example
{
public void Test()
{
var byAction = new DelegatePublisher(onDelegate);
}
private void onDelegate(byte[] buffer, int index, int count)
{
// do stuff
}
}
一旦 Invoke
被调用,动作就会被调用。 (为了这个最小的例子,我特意省略了所有 null
检查)
这按预期工作,我对这个解决方案很满意。但是,人们一直告诉我应该使用 Events
。我告诉他们我只需要调用一个 single Action
,并且代码可以完美地完成。经过长时间的讨论,现在的代码如下所示:
public class EventPublisher
{
public EventHandler<EventPublisherEventArgs> OnCompleted;
public void Invoke(byte[] buffer, int index, int count)
{
var handler = OnCompleted;
if (handler != null)
{
handler(this, new EventPublisherEventArgs(buffer, index, count));
}
}
}
当然还有 EventArgs
:
public class EventPublisherEventArgs : EventArgs
{
public byte[] Buffer
{
get;
private set;
}
public int Index
{
get;
private set;
}
public int Count
{
get;
private set;
}
public EventPublisherEventArgs(byte[] buffer, int index, int count)
{
Buffer = buffer;
Index = index;
Count = count;
}
}
我的...好吧,"calling" 代码现在看起来像这样:
public class Example
{
public void Test()
{
var byEvent = new EventPublisher();
byEvent.OnCompleted += onEvent;
}
private void onEvent(object sender, EventPublisherEventArgs e)
{
// do stuff
}
}
作为Event
这样做真的有什么好处吗?或者反过来:使用 Action
?
的方式有问题吗?
我可以通过使用 Events
知道我需要更多代码,有一个额外的抽象层,可能连接多个(不需要的)回调并且需要一个额外的 class 只是为了持有三个参数。我看到的唯一好处是我遵循了一个共同的模式。但是,我已经看到很多代码将动作作为参数传递,即使在 BCL 中也是如此,这也可以通过事件来解决。
Is there actually any benefit in doing it as an Event?
虽然非常自以为是,但我会尝试表达我的观点。
我没有看到任何直接的好处。这通常取决于你需要什么。事件只是委托的包装器,它们增加了另一个抽象级别(如您所说)。
你必须使用它们吗?不,我认为您的 工作代码示例 没有任何问题。不符合使用某些模式,因为 "people think they're better"。关注它们是因为您已经看到使用它们的明显好处。在这种特殊情况下,我看不到任何附加值。
在我的场景中,我有一个 class 会时不时地为我做一些工作,偶尔会对它做出一些反应。实际操作是什么将由外部提供。我认为值得一提的是,只有 一个 外部实例告诉这个 class 必须做什么。
我已经实现了这样的东西:
public class DelegatePublisher
{
private Action<byte[], int, int> onCompleted;
public DelegatePublisher(Action<byte[], int, int> onCompleted)
{
this.onCompleted = onCompleted;
}
public void Invoke(byte[] buffer, int index, int count)
{
onCompleted.Invoke(buffer, index, count);
}
}
这可以在以后简单地使用:
public class Example
{
public void Test()
{
var byAction = new DelegatePublisher(onDelegate);
}
private void onDelegate(byte[] buffer, int index, int count)
{
// do stuff
}
}
一旦 Invoke
被调用,动作就会被调用。 (为了这个最小的例子,我特意省略了所有 null
检查)
这按预期工作,我对这个解决方案很满意。但是,人们一直告诉我应该使用 Events
。我告诉他们我只需要调用一个 single Action
,并且代码可以完美地完成。经过长时间的讨论,现在的代码如下所示:
public class EventPublisher
{
public EventHandler<EventPublisherEventArgs> OnCompleted;
public void Invoke(byte[] buffer, int index, int count)
{
var handler = OnCompleted;
if (handler != null)
{
handler(this, new EventPublisherEventArgs(buffer, index, count));
}
}
}
当然还有 EventArgs
:
public class EventPublisherEventArgs : EventArgs
{
public byte[] Buffer
{
get;
private set;
}
public int Index
{
get;
private set;
}
public int Count
{
get;
private set;
}
public EventPublisherEventArgs(byte[] buffer, int index, int count)
{
Buffer = buffer;
Index = index;
Count = count;
}
}
我的...好吧,"calling" 代码现在看起来像这样:
public class Example
{
public void Test()
{
var byEvent = new EventPublisher();
byEvent.OnCompleted += onEvent;
}
private void onEvent(object sender, EventPublisherEventArgs e)
{
// do stuff
}
}
作为Event
这样做真的有什么好处吗?或者反过来:使用 Action
?
我可以通过使用 Events
知道我需要更多代码,有一个额外的抽象层,可能连接多个(不需要的)回调并且需要一个额外的 class 只是为了持有三个参数。我看到的唯一好处是我遵循了一个共同的模式。但是,我已经看到很多代码将动作作为参数传递,即使在 BCL 中也是如此,这也可以通过事件来解决。
Is there actually any benefit in doing it as an Event?
虽然非常自以为是,但我会尝试表达我的观点。
我没有看到任何直接的好处。这通常取决于你需要什么。事件只是委托的包装器,它们增加了另一个抽象级别(如您所说)。
你必须使用它们吗?不,我认为您的 工作代码示例 没有任何问题。不符合使用某些模式,因为 "people think they're better"。关注它们是因为您已经看到使用它们的明显好处。在这种特殊情况下,我看不到任何附加值。