Apakah ini bug?
Iya.
Selamat, Anda menemukan bug dalam resolusi kelebihan beban. Bug mereproduksi di C # 4 dan 5; itu tidak mereproduksi dalam versi "Roslyn" dari penganalisis semantik. Saya telah memberi tahu tim penguji C # 5, dan mudah-mudahan kami dapat menyelidiki dan menyelesaikan masalah ini sebelum rilis final. (Seperti biasa, tidak ada janji.)
Analisis yang benar mengikuti. Kandidatnya adalah:
0: C(params string[]) in its normal form
1: C(params string[]) in its expanded form
2: C<string>(string)
3: C(string, object)
Kandidat nol jelas tidak dapat diterapkan karena string
tidak dapat dikonversi string[]
. Tinggal tiga.
Dari ketiganya, kita harus menentukan metode unik terbaik. Kami melakukannya dengan membuat perbandingan berpasangan dari tiga kandidat yang tersisa. Ada tiga pasangan seperti itu. Semuanya memiliki daftar parameter yang identik setelah kita menghapus parameter opsional yang dihilangkan, yang berarti kita harus pergi ke putaran tiebreaking lanjutan yang dijelaskan dalam bagian 7.5.3.2 spesifikasi.
Mana yang lebih baik, 1 atau 2? Tiebreaker yang relevan adalah bahwa metode generik selalu lebih buruk daripada metode non-generik. 2 lebih buruk dari 1. Jadi 2 tidak bisa menjadi pemenang.
Mana yang lebih baik, 1 atau 3? Tiebreak yang relevan adalah: metode yang hanya dapat diterapkan dalam bentuk yang diperluas selalu lebih buruk daripada metode yang dapat diterapkan dalam bentuk normalnya. Oleh karena itu 1 lebih buruk dari 3. Jadi 1 tidak bisa menjadi pemenang.
Mana yang lebih baik, 2 atau 3? Tiebreaker yang relevan adalah bahwa metode generik selalu lebih buruk daripada metode non-generik. 2 lebih buruk dari 3. Jadi 2 tidak bisa menjadi pemenang.
Untuk dipilih dari sekumpulan beberapa kandidat yang berlaku, seorang kandidat harus (1) tidak terkalahkan, (2) mengalahkan setidaknya satu kandidat lainnya, dan (3) menjadi kandidat unik yang memiliki dua properti pertama. Kandidat tiga dikalahkan oleh kandidat lain, dan mengalahkan setidaknya satu kandidat lainnya; itu adalah satu-satunya kandidat dengan properti ini. Oleh karena itu, kandidat ketiga adalah kandidat terbaik yang unik . Ini harus menang.
Tidak hanya compiler C # 4 yang salah, seperti yang Anda catat dengan benar, compiler ini melaporkan pesan kesalahan yang aneh. Bahwa kompiler salah melakukan analisis resolusi kelebihan beban sedikit mengejutkan. Bahwa mendapatkan pesan kesalahan yang salah sama sekali tidak mengejutkan; heuristik kesalahan "metode ambigu" pada dasarnya mengambil dua metode dari kumpulan kandidat jika metode terbaik tidak dapat ditentukan. Tidaklah pandai menemukan ambiguitas yang "sebenarnya", jika sebenarnya ada.
Orang mungkin bertanya mengapa demikian. Sangat sulit untuk menemukan dua metode yang "sangat ambigu" karena hubungan "betterness" adalah intransitif . Ada kemungkinan untuk menghadapi situasi di mana kandidat 1 lebih baik dari 2, 2 lebih baik dari 3, dan 3 lebih baik dari 1. Dalam situasi seperti itu, kita tidak dapat melakukan lebih baik daripada memilih dua di antaranya sebagai "yang ambigu".
Saya ingin meningkatkan heuristik ini untuk Roslyn tetapi ini adalah prioritas rendah.
(Latihan untuk pembaca: "Rancang algoritma waktu linier untuk mengidentifikasi anggota terbaik yang unik dari himpunan n elemen di mana hubungan betterness adalah intransitif" adalah salah satu pertanyaan yang saya tanyakan pada hari saya mewawancarai tim ini. Bukan algoritma yang sangat sulit; cobalah.)
Salah satu alasan mengapa kami menunda untuk menambahkan argumen opsional ke C # untuk waktu yang lama adalah banyaknya situasi ambigu kompleks yang diperkenalkannya ke dalam algoritma resolusi berlebih; ternyata kami tidak melakukannya dengan benar.
Jika Anda ingin memasukkan masalah Hubungkan untuk melacaknya, silakan. Jika Anda hanya ingin hal itu diperhatikan kami, anggap saja sudah selesai. Saya akan menindaklanjuti dengan pengujian tahun depan.
Terima kasih sudah membawa ini padaku. Maaf atas kesalahannya.
'Overloaded.ComplexOverloadResolution(string)'
mengacu pada<string>(string)
metode; Saya pikir ini mengacu pada(string, object)
metode tanpa objek yang diberikan.