Kode berikut memiliki metode statis, Foo()
, memanggil metode contoh, Bar()
:
public sealed class Example
{
int count;
public static void Foo( dynamic x )
{
Bar(x);
}
void Bar( dynamic x )
{
count++;
}
}
Ini mengkompilasi tanpa kesalahan * tetapi menghasilkan pengecualian pengikat runtime pada saat runtime. Menghapus parameter dinamis ke metode ini menyebabkan kesalahan kompiler, seperti yang diharapkan.
Jadi mengapa memiliki parameter dinamis memungkinkan kode untuk dikompilasi? ReSharper juga tidak menampilkannya sebagai kesalahan.
Edit 1: * dalam Visual Studio 2008
Edit 2: ditambahkan sealed
karena ada kemungkinan subclass dapat berisi Bar(...)
metode statis . Bahkan versi tersegel dapat dikompilasi ketika tidak mungkin metode apa pun selain metode instance dapat dipanggil saat runtime.
c#
visual-studio-2008
dynamic
compiler-errors
Mike Scott
sumber
sumber
dynamic
kecuali Anda benar-benar perlu.Jawaban:
PEMBARUAN: Di bawah jawaban ditulis pada tahun 2012, sebelum pengenalan C # 7.3 (Mei 2018) . Dalam Yang baru di C # 7.3 , bagian Kandidat kelebihan muatan yang ditingkatkan , item 1, dijelaskan bagaimana aturan resolusi kelebihan muatan telah berubah sehingga muatan berlebih non-statis dibuang lebih awal. Jadi jawaban di bawah ini (dan seluruh pertanyaan ini) sebagian besar hanya memiliki kepentingan sejarah sekarang!
(Sebelum C # 7.3 :)
Untuk beberapa alasan, resolusi kelebihan beban selalu menemukan kecocokan terbaik sebelum memeriksa statis versus non-statis. Silakan coba kode ini dengan semua jenis statis:
Ini tidak akan dikompilasi karena kelebihan beban terbaik adalah yang mengambil file
string
. Tapi hei, itu adalah metode instance, jadi compiler mengeluh (alih-alih mengambil overload terbaik kedua).Tambahan: Jadi menurut saya penjelasan dari
dynamic
contoh Pertanyaan Asli adalah, agar konsisten, ketika tipe dinamis kita juga pertama-tama menemukan kelebihan beban terbaik (hanya memeriksa nomor parameter dan jenis parameter dll., Bukan statis vs. non -static), dan hanya setelah itu periksa statis. Namun itu berarti pemeriksaan statis harus menunggu hingga waktu proses. Oleh karena itu perilaku yang diamati.Tambahan yang terlambat: Beberapa latar belakang mengapa mereka memilih untuk melakukan sesuatu agar lucu ini dapat disimpulkan dari posting blog ini oleh Eric Lippert .
sumber
dynamic
diperkenalkan dalam bahasa tersebut, saya pikir perancang C # berkata: "Kami tidak akan mempertimbangkan (2) waktu kompilasi ketika itu adalahdynamic
ekspresi." Jadi tujuan saya di sini adalah untuk mendapatkan ide tentang mengapa mereka memilih untuk tidak memeriksa contoh statis versus sampai runtime. Saya akan mengatakan, pemeriksaan ini terjadi pada waktu yang mengikat .Foo memiliki parameter "x" yang dinamis, yang artinya Bar (x) adalah ekspresi dinamis.
Sangat mungkin bagi Contoh untuk memiliki metode seperti:
Dalam hal ini metode yang benar akan diselesaikan, jadi pernyataan Bar (x) benar-benar valid. Fakta bahwa ada metode instance Bar (x) tidak pernah terjadi dan bahkan tidak dianggap: menurut definisi , karena Bar (x) adalah ekspresi dinamis, kami telah menangguhkan resolusi ke runtime.
sumber
Ekspresi "dinamis" akan terikat selama runtime, jadi jika Anda mendefinisikan metode statis dengan tanda tangan yang benar atau metode instance, kompilator tidak akan memeriksanya.
Metode yang "benar" akan ditentukan selama runtime. Kompilator tidak dapat mengetahui apakah ada metode yang valid di sana selama runtime.
Kata kunci "dinamis" ditentukan untuk bahasa dinamis dan skrip, di mana Metode dapat ditentukan kapan saja, bahkan selama waktu proses. Hal gila
Di sini contoh yang menangani int tetapi tidak ada string, karena metode tersebut ada di instance.
Anda dapat menambahkan metode untuk menangani semua panggilan "salah", yang tidak dapat ditangani
sumber