2

关于是否强类型事件参数有很多讨论。这个问题与此无关。我有以下课程(仅包含相关代码):

public abstract class Thread<TSender, TEventArgs>:
    System.IDisposable
    where TSender: Thread<TSender, TEventArgs>, new()
    where TEventArgs: System.EventArgs, new()
{
    public delegate void ThreadEventHandler (Thread<TSender, TEventArgs> sender, ThreadEventArgs e);

    // This declaratino generates a VS 2012 warning.
    public delegate void ThreadProcessIterationEventHandler<TSender, TEventArgs> (TSender sender, TEventArgs e);
}

第二个委托的声明会生成 VS2012 警告:

1. Type parameter 'TSender' has the same name as the type parameter from outer type 'Thread<TSender,TEventArgs>'

2. Type parameter 'TEventArgs' has the same name as the type parameter from outer type 'Thread<TSender,TEventArgs>'

这种结构在逻辑上似乎是正确的,因为其目的是为派生类提供包装的线程机制。它当然是合法的代码,可以按预期编译和运行。

我会认为有一个自我指向约束可能被认为是不好的做法,但为什么被TSender标记TEventArgs为警告?这和声明不一样NestedClass<TSender, TEventArgs>吗?

我应该注意些什么吗?

更新:第二个委托的目的是允许子类触发强类型事件。

4

2 回答 2

9

您正在声明一个委托,带有新的类型说明符。您可以在没有额外的泛型类型的情况下声明它:

public delegate void ThreadProcessIterationEventHandler(TSender sender, TEventArgs e);

通过将 放在<TSender,TEventArgs>委托声明中,它定义了在委托中使用的新类型,其名称与包含的泛型类型相同。就像你在写:

public delegate void ThreadProcessIterationEventHandler<TFoo, TBar>(TFoo sender, TBar e);

基本上,通过添加这些类型,您实际上可以使委托使用与包含类不同的类型。由于您使用了相同的名称,编译器认为这是一个错误,并警告您。

于 2013-07-01T17:52:05.553 回答
6

这是第二个失败的声明:

ThreadProcessIterationEventHandler<TSender, TEventArgs>(...)

您不能声明在已经声明类型参数的类型中调用的类型参数。TSenderTSender

你不想要一个新的泛型类型——你只想重用封闭类型的类型参数:

public delegate void ThreadProcessIterationEventHandler(TSender sender, TEventArgs e);
于 2013-07-01T17:52:02.337 回答