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

时间:2014-10-03 10:21:50

标签: c# events generics delegates eventargs

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

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

我该怎么做?

2 个答案:

答案 0 :(得分:2)

事件声明不能是(开放)通用的。他们可以从声明类型使用泛型类型参数,但是它们不能声明自己的泛型参数。因此,只有声明Result的类型具有T(直接或通过外部类型),即如果它是SomeManager<T>时,您才能实现所需:

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

然后T就是上面的一切;在SomeManager<int>中,它将是EventHandler<TimedResult<int>>,依此类推。

答案 1 :(得分:2)

  

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

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类型参数,并将接口类型转换为具体在事件处理程序中需要时实现。