事件声明中泛型的正确使用



我有一个可以传递的数据对象:

public class TimedResult<T>
{
    public ResultRequest Request { get; set; }
    public T Data { get; set; }
    public TimeSpan TimeTaken { get; set; }
}

在我的经理课上,我做了一些工作,这引发了一个事件:

public void Execute(ResultRequest request)
{
    var result = new TimedResult<DataTable>();
    // fill data object here
    OnResult(result);
}

我已经使OnResult方法通用:

protected virtual void OnResult<T>(TimedResult<T> result)
{
    if (Result != null)
        Result(this, result);
}

但是如何使事件声明通用

public event EventHandler<TimedResult<T>> Result; // red line under T

我应该怎么做

事件声明不能是(开放的)泛型。它们可以使用声明类型中的泛型类型参数,但不能声明自己的泛型参数。因此,只有当声明Result的类型有一个T(直接或通过外部类型)时,即如果这是SomeManager<T>:,您想要的才是可能的

class SomeManager<T> {
     public event EventHandler<TimedResult<T>> Result;
}

则CCD_ 5是来自上面的任何值;在SomeManager<int>中,它将是EventHandler<TimedResult<int>>,依此类推。

但是,如何使事件声明通用呢?

public event EventHandler<TimedResult<T>> Result; // red line under T

声明整个事件的类也应该是泛型(即它应该有一个泛型类型参数):

public class X<TEventData>
{
    public event EventHandler<TimedResult<TEventData>> Result; // red line under T
}

现在,根据您的要求,这是否有效,因为如果您希望用多个事件数据类型引发事件,您可以使用反射来解决引发事件的问题(避免这种情况)。

或者,我建议您设计一个接口,该接口应定义任何给定的事件数据共享一些成员,将该接口作为X<TEventData> TEventData类型参数,并在事件处理程序中需要时将接口类型强制转换为具体实现。

最新更新