コンパイラの理解できない動作に少し困惑しています。次のコード サンプルに減らしました。
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>
Handler
IFoo
IBar<int>
Handler
DHandler<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
、型パラメーターが必要な理由を説明するかもしれません。しかし、誰でもこれに光を当てることができますか?