我对编译器无法理解的一些行为感到有些困惑。我已将其简化为以下代码示例:
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>HandlerIFoo IBar<int>HandlerDHandler<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“。这可以解释为什么它需要类型参数。但是任何人都可以对此有所了解吗?