【问题标题】:Correct usage of generics in event declaration在事件声明中正确使用泛型
【发布时间】:2014-10-03 10:21:50
【问题描述】:

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

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

我应该怎么做?

【问题讨论】:

  • T 来自哪里?它应该是类定义的一部分class Manager&lt;T&gt;
  • @lc。好问题,我对泛型不太熟悉,我想我想做的是能够使用相同的OnResult 方法和事件返回TimedResult&lt;DataTable&gt;TimedResult&lt;int&gt;
  • @Muhammad 那么你最好的选择是使用object,即public event EventHandler&lt;TimedResult&lt;object&gt;&gt; Result;;p
  • 这有点 XY 但快速查看,我认为您正在尝试异步执行某些操作并返回结果。为什么不直接使用 TPL?在Execute 方法中返回一个等待的Task,您根本不需要该事件:public async Task&lt;T&gt; Execute(ResultRequest request) {...}。当然,我假设执行的人是监听结果的人。
  • @MarcGravell 是的,这就是我在决定随机将 T 放在那里之前所拥有的东西:D

标签: c# events generics delegates eventargs


【解决方案1】:

事件声明不能是(开放的)通用的。他们可以使用来自声明类型的泛型类型参数,但不能声明自己的泛型参数。因此,只有当声明 Result 的类型具有 T(直接或通过外部类型)时,您想要的才有可能,即如果这是 SomeManager&lt;T&gt;

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

那么T 就是上面的任何东西;在SomeManager&lt;int&gt; 中,它将是EventHandler&lt;TimedResult&lt;int&gt;&gt; 等等。

【讨论】:

    【解决方案2】:

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

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

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

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

    现在,根据您的要求,这是否可行,因为如果您正在寻找引发事件的不仅仅是事件数据类型,您可以使用反射来解决引发事件的问题(避免这种情况)。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-30
      • 1970-01-01
      • 2011-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-26
      相关资源
      最近更新 更多