=============
UPDATE: Saya menggunakan jawaban ini sebagai dasar untuk entri blog ini:
Mengapa parameter ref dan out tidak mengizinkan variasi jenis?
Lihat halaman blog untuk komentar lebih lanjut tentang masalah ini. Terima kasih atas pertanyaan bagusnya.
=============
Mari kita misalkan Anda memiliki kelas Animal
, Mammal
, Reptile
, Giraffe
, Turtle
dan Tiger
, dengan hubungan subclassing jelas.
Sekarang misalkan Anda memiliki metode void M(ref Mammal m)
. M
bisa membaca dan menulis m
.
Bisakah Anda mengirimkan variabel tipe Animal
ke M
?
Tidak. Variabel tersebut dapat berisi a Turtle
, tetapi M
akan menganggap bahwa variabel tersebut hanya berisi Mamalia. A Turtle
bukan Mammal
.
Kesimpulan 1 : ref
Parameter tidak bisa dibuat "lebih besar". (Ada lebih banyak hewan daripada mamalia, jadi variabelnya menjadi "lebih besar" karena bisa berisi lebih banyak hal.)
Bisakah Anda mengirimkan variabel tipe Giraffe
ke M
?
Tidak. M
Bisa menulis ke m
, dan M
mungkin ingin menulis Tiger
ke m
. Sekarang Anda telah memasukkan a Tiger
ke dalam variabel yang sebenarnya bertipe Giraffe
.
Kesimpulan 2 : ref
Parameter tidak bisa dibuat "lebih kecil".
Sekarang pertimbangkan N(out Mammal n)
.
Bisakah Anda mengirimkan variabel tipe Giraffe
ke N
?
Tidak. N
Dapat menulis ke n
, dan N
mungkin ingin menulis Tiger
.
Kesimpulan 3 : out
Parameter tidak bisa dibuat "lebih kecil".
Bisakah Anda mengirimkan variabel tipe Animal
ke N
?
Hmm.
Nah, kenapa tidak? N
tidak bisa membaca n
, hanya bisa menulis padanya, bukan? Anda menulis Tiger
ke variabel tipe Animal
dan Anda sudah siap, bukan?
Salah. Aturannya bukanlah " N
hanya dapat menulis ke n
".
Aturannya adalah, secara singkat:
1) N
harus menulis n
sebelum N
kembali normal. (Jika N
melempar, semua taruhan dibatalkan.)
2) N
harus menulis sesuatu n
sebelum membaca sesuatu dari n
.
Itu memungkinkan urutan kejadian ini:
- Deklarasikan bidang
x
tipe Animal
.
- Teruskan
x
sebagai out
parameter ke N
.
N
menulis Tiger
ke n
, yang merupakan alias untuk x
.
- Di utas lain, seseorang menulis
Turtle
ke x
.
N
mencoba membaca isi dari n
, dan menemukan a Turtle
dalam apa yang dianggapnya sebagai variabel tipe Mammal
.
Jelas kami ingin membuatnya ilegal.
Kesimpulan 4 : out
Parameter tidak bisa dibuat "lebih besar".
Kesimpulan akhir : Baik parameter ref
maupun out
parameter tidak dapat mengubah jenisnya. Melakukan sebaliknya adalah merusak jenis keamanan yang dapat diverifikasi.
Jika masalah-masalah dalam teori tipe dasar ini menarik minat Anda, pertimbangkan untuk membaca seri saya tentang bagaimana kovarians dan kontravarian bekerja di C # 4.0 .