我对编译器无法理解的一些行为感到有些困惑.我已将其缩减为以下代码示例:
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) { }
}
Run Code Online (Sandbox Code Playgroud)
我的问题是我不希望代码编译,但确实如此.我不希望它编译,因为签名中DHandler<int>需要IBar<int>,但Handler方法声明IFoo,这不是 IBar<int>(虽然反过来是真的).因此Handler不是a DHandler<int>,因此它的委托不能用作Garply<int>调用的参数.
如果我改变代码来读取Handler(IBar<int> arg)它编译.如果我改变它来阅读Handler(IBar<string> arg)它没有.这些行为都是我所期望的.
提示这个问题的实际问题是,当签名是Handler(IBar<int> arg),编译器抱怨我需要显式指定Garply调用的类型参数.在这个例子中是微不足道的,但在实际的代码中,这将是一个真正的麻烦.我很神秘,因为参数Garply是一个带签名的方法(IBar<int> arg),因此它的委托将是一个DHandler<int> …