私はいくつかの単体テストを書いていますが、実際にはリファクタリング後に単体テストを修正していて、非常に奇妙な動作に気付きました。元のアサーションは、AreEqual メソッドの非ジェネリック フレーバーを使用していました。
Assert.AreEqual(Foo.Do(...), Bar.Do(...).Conversion(...));
いくつかのリファクタリングの後、Foo.Do() は同じ型を返さなくなり、同等性を維持するために追加の変換が必要になりました。ただし、AreEquals 関数は喜んで任意のオブジェクトを取得するため、コンパイル時ではなく実行時にテストが失敗します。
そこで、アサーションを対応する一般的なアサーションに変更して、将来このような変更がコンパイル時エラーになることを強制することにしました。
Assert.AreEqual<X>(Foo.Do(...), Bar.Do(...).Conversion(...));
この時点では、正しい型を返すように Foo.Do() を変更していないため、Foo.Do() の戻り値が X ではないというコンパイル エラーが発生するはずです。驚いたことに、何も起こりません。コンパイルは問題なく成功します。どこかで型の間に暗黙的な変換があるに違いないと思いますが、少し実験してみるとそうではありません。関数の非ジェネリックおよびジェネリック フレーバーがこのように相互作用するかどうかを確認するために、他のいくつかのモック例を試しましたが、このクラス以外ではこの動作を再現できません。
Visual Studio で関数にカーソルを合わせると X 型を意味するように見えるのに、なぜコンパイラは両方の値が X 型であることを強制しないのですか?