Saya tidak menghadiri PDC 2008, tetapi saya mendengar beberapa berita bahwa C # 4.0 diumumkan untuk mendukung kovarians Generik dan kontra-varian. Artinya, List<string>
bisa ditugaskan ke List<object>
. Bagaimana bisa?
Dalam buku Jon Skeet C # in Depth , dijelaskan mengapa C # generik tidak mendukung kovariansi dan kontra-varian. Ini terutama untuk menulis kode aman. Sekarang, C # 4.0 berubah untuk mendukung mereka. Apakah itu akan membawa kekacauan?
Adakah yang tahu detail tentang C # 4.0 dapat memberikan penjelasan?
c#
c#-4.0
covariance
contravariance
generic-variance
Morgan Cheng
sumber
sumber
Jawaban:
Varians hanya akan didukung dengan cara yang aman - pada kenyataannya, menggunakan kemampuan yang sudah dimiliki CLR. Jadi contoh yang saya berikan dalam buku tentang mencoba menggunakan a
List<Banana>
sebagaiList<Fruit>
(atau apa pun itu) tetap tidak akan berhasil - tetapi beberapa skenario lain akan berhasil.Pertama, ini hanya akan didukung untuk antarmuka dan delegasi.
Kedua, memerlukan pembuat antarmuka / delegasi untuk menghias parameter tipe sebagai
in
(untuk kontradiksi) atauout
(untuk kovarian). Contoh yang paling jelas adalahIEnumerable<T>
yang hanya memungkinkan Anda mengambil nilai "keluar" darinya - tidak memungkinkan Anda menambahkan nilai baru. Itu akan menjadiIEnumerable<out T>
. Itu tidak mengganggu keamanan tipe sama sekali, tetapi memungkinkan Anda mengembalikanIEnumerable<string>
dari metode yang dideklarasikan untuk dikembalikanIEnumerable<object>
misalnya.Kontradiksi lebih sulit untuk memberikan contoh konkret untuk menggunakan antarmuka, tetapi mudah dengan delegasi. Pertimbangkan
Action<T>
- itu hanya mewakili metode yang mengambilT
parameter. Akan menyenangkan untuk dapat mengonversi dengan mulus menggunakan anAction<object>
sebagaiAction<string>
- metode apa pun yang menggunakanobject
parameter akan baik-baik saja ketika disajikan dengan astring
sebagai gantinya. Tentu saja, C # 2 sudah memiliki kovariansi dan kontradiksi delegasi sampai batas tertentu, tetapi melalui konversi aktual dari satu jenis delegasi ke jenis lainnya (membuat instans baru) - lihat P141-144 sebagai contoh. C # 4 akan membuat ini lebih umum, dan (saya percaya) akan menghindari membuat contoh baru untuk konversi. (Alih-alih, ini akan menjadi konversi referensi.)Semoga ini sedikit menyelesaikannya - beri tahu saya jika tidak masuk akal!
sumber
List<Banana>
sebagaiIList<Fruit>
" seperti yang dikatakan @ Ark-kun? Jika demikian, bagaimana ini mungkin, meskipun parameter tipeIList<T>
antarmuka tidak didefinisikan sebagai kovarian (tidakout T
, tetapi sederhanaT
).Bukan berarti Jon belum membahasnya, tetapi berikut beberapa tautan ke blog dan video dari Eric Lippert. Dia melakukan pekerjaan yang bagus dalam menjelaskannya dengan contoh-contoh.
https://blogs.msdn.microsoft.com/ericlippert/2007/10/16/covariance-and-contravariance-in-c-part-one/
Video:
https://www.youtube.com/watch?v=3MQDrKbzvqU
https://www.youtube.com/watch?v=XRIadQaBYlI
https://www.youtube.com/watch?v=St9d2EDZfrg
sumber