为什么在Class <T>中声明Delegate <T>会生成VS警告?

Rah*_*han 2 .net c# generics delegates

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

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);
}
Run Code Online (Sandbox Code Playgroud)

第二个代表的声明生成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>'
Run Code Online (Sandbox Code Playgroud)

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

我本来以为,有一个自指向约束可能被认为是不好的做法,但为什么TSenderTEventArgs标记为警告?这与申报不一样NestedClass<TSender, TEventArgs>吗?

我应该注意什么吗?

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

Ree*_*sey 9

您正在使用新的类型说明符声明委托.您可以在没有额外泛型类型的情况下声明:

public delegate void ThreadProcessIterationEventHandler(TSender sender, TEventArgs e);
Run Code Online (Sandbox Code Playgroud)

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

public delegate void ThreadProcessIterationEventHandler<TFoo, TBar>(TFoo sender, TBar e);
Run Code Online (Sandbox Code Playgroud)

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


Jon*_*eet 6

这是失败的第二个宣言:

ThreadProcessIterationEventHandler<TSender, TEventArgs>(...)
Run Code Online (Sandbox Code Playgroud)

您不能声明在已声明类型参数的类型中调用的TSender类型参数TSender.

你不希望一个新的通用型,但-你只是想重用封闭类型的类型参数:

public delegate void ThreadProcessIterationEventHandler(TSender sender, TEventArgs e);
Run Code Online (Sandbox Code Playgroud)