我对编译器无法理解的一些行为感到有些困惑。我已将其简化为以下代码示例:
public interface IFoo { }
public interface IBar<T> : IFoo { }
public delegate void DHandler<T>(IBar<T> arg);
public static class Demo
{
static void Garply<T>(DHandler<T> handler) { }
public static void DoStuffWithInt()
{
Garply<int>(Handler);
}
static void Handler(IFoo arg) { }
}
我的问题是我不希望代码编译,但确实如此。我不希望它编译,因为在签名中DHandler<int>
需要,但是方法声明了,但事实并非如此(尽管反之亦然)。因此不是 a ,因此它的委托不能用作调用的参数。IBar<int>
Handler
IFoo
IBar<int>
Handler
DHandler<int>
Garply<int>
如果我更改代码以读取Handler(IBar<int> arg)
它会编译。如果我将其更改为阅读Handler(IBar<string> arg)
,则不会。这两种行为都符合我的预期。
提示这个问题的实际问题是,当签名为 时Handler(IBar<int> arg)
,编译器抱怨我需要显式指定Garply
调用的类型参数。在这个例子中微不足道,但在实际代码中,这将是一个真正的麻烦。我很困惑,因为 to 的参数Garply
是一个带有签名的方法(IBar<int> arg)
,所以它的委托将是 a DHandler<int>
,所以选择的Garply<T>
将是明确的Garply<int>
。但显然编译器看到了歧义。它正在调查,这导致我遇到上述难题,我只能猜测编译器可能在想“好吧,令杰森惊讶的是,我已经接受了 an IFoo
,IBar<T>
所以T
必须指定 a 让我知道我应该把它编译为IBar<T>
而不是IFoo
“。这可以解释为什么它需要类型参数。但是任何人都可以对此有所了解吗?