5

重複の可能性:
ジェネリック メソッドとメソッドのオーバーロード

次のようなクラスがあるとします

class SortedList<K>
{
    public string this[int i] { get { return "a"; /* dummy sample code */ } }
    public string this[K key] { get { return "b"; /* dummy sample code */ } }
}

さて、何人かの男がそれを使用することを決定したとしましょう:

static string Test1<K>(K key) { return new SortedList<K>()[key]; }

コンパイラは、この呼び出しをK keyオーバーロードに解決します。

さて、これを言うことと対比してください

static string Test2(int key) { return new SortedList<int>()[key]; }  // whoops

コンパイラはこれをint iオーバーロードに解決します。

さて、哀れな魂が と言うTest1(0)なら、彼が言った場合とは異なる結果を得るだろうTest2(0)

おかしなことに、どちらの場合も、コンパイラまたはランタイムはあいまいさを検出せず、エラーが発生しません。
代わりに、ランタイムは、値がジェネリックかどうかに関して動作を変更するだけであり、これは呼び出し元にとって明らかに予期しないものになる可能性があります。

行動が一貫していないのはなぜですか?
または、さらに良いことに、あいまいさのためにコンパイラ (または実行時) エラーが発生しないのはなぜですか?

4

2 に答える 2

0

なぜハックが一貫性のない動作だと思いますか? 「たぶんキー」タイプのゲッターでインデックスゲッターをオーバーライドすることがポイントです...

期待される結果はどうあるべきだと思いますか?警告?開発者は、どのジェネリックにどのタイプを使用するかを確認する必要があります...メソッド「test1」がキーベースのゲッターに対処し、test2がインデックスベースのゲッターにのみ対処することを確認するのに十分なほどインテリジェントです...

タイプとして「int」を許可しない(たとえば、クラス制約を使用)か、ここに他のゲッターメソッドを実装する必要があります...

于 2012-08-26T06:21:58.153 に答える
0

コンパイラは、あいまいに見える可能性があると思われるものについて、警告やエラーを呼び出さないためです。あいまいであることがわかったものを呼び出します。しかし、ここでコンパイラーにとってあいまいなことは何もありません。

正方形と長方形を渡して、正方形を a の山に、長方形を b の山に入れるように指示したとします。さらに、オブジェクトには既にそのようにラベルが付けられているため、それらが正方形か長方形かを確認するためにオブジェクトを見る必要はありません。さて...ある時点で、長方形としてマークされたオブジェクトを手渡しましたが、それがたまたま正方形でもあることに気づきました。オブジェクトを分析するように言ったのではありません... 指示に従い、ラベル付けした方法に従ってそれらを整理するように言いました。そして、それがコンパイラーの仕組みです...あなたが指示したことを正確に実行します。

于 2012-08-26T06:22:21.830 に答える