コンパイラの理解できない動作に少し困惑しています。次のコード サンプルに減らしました。
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>必要なため、コンパイルすることは期待していませんが、メソッドは を宣言していますが、そうではありません(逆は真です)。したがって、 は ではないため、デリゲートを呼び出しの引数として使用することはできません。IBar<int>HandlerIFoo IBar<int>HandlerDHandler<int>Garply<int>
コードを変更して読み取るHandler(IBar<int> arg)と、コンパイルされます。読むように変更しても、Handler(IBar<string> arg)そうではありません。これらの動作は両方とも、私が期待するとおりです。
この質問を促す実際的な問題は、署名が の場合、呼び出しHandler(IBar<int> arg)の型パラメーターを明示的に指定する必要があるとコンパイラーが不平を言うことです。Garplyこの例では些細なことですが、実際のコードでは非常に厄介です。への引数Garplyは署名付きのメソッドである(IBar<int> arg)ため、それへのデリゲートは になりDHandler<int>、選択されたGarply<T>は明確に になるため、私は戸惑いましたGarply<int>。しかし、どうやらコンパイラはあいまいさを見ました。IFooそれが私を上記のパズルに導いたことを調査していましIBar<T>た.おそらくコンパイラーが考えていると推測Tできます.私はそれを次のようにコンパイルする必要がありますIBar<T>「としてではなくIFoo、型パラメーターが必要な理由を説明するかもしれません。しかし、誰でもこれに光を当てることができますか?