Apa perbedaan antara <out T>
dan <T>
? Sebagai contoh:
public interface IExample<out T>
{
...
}
vs.
public interface IExample<T>
{
...
}
c#
generics
covariance
Cole Johnson
sumber
sumber
Jawaban:
Kata
out
kunci dalam generik digunakan untuk menunjukkan bahwa tipe T di antarmuka adalah kovarian. Lihat Covariance dan contravariance untuk detailnya.Contoh klasiknya adalah
IEnumerable<out T>
. KarenaIEnumerable<out T>
kovarian, Anda diperbolehkan melakukan hal berikut:Baris kedua di atas akan gagal jika ini bukan kovarian, meskipun secara logis seharusnya bekerja, karena string berasal dari objek. Sebelum variasi dalam antarmuka umum ditambahkan ke C # dan VB.NET (dalam .NET 4 dengan VS 2010), ini adalah kesalahan waktu kompilasi.
Setelah .NET 4,
IEnumerable<T>
ditandai kovarian, dan menjadiIEnumerable<out T>
. KarenaIEnumerable<out T>
hanya menggunakan elemen di dalamnya, dan tidak pernah menambahkan / mengubahnya, aman untuk memperlakukan kumpulan string yang dapat dihitung sebagai kumpulan objek yang dapat dihitung, yang berarti kovarian .Ini tidak akan bekerja dengan tipe seperti
IList<T>
, karenaIList<T>
memilikiAdd
metode. Misalkan ini diizinkan:Anda kemudian dapat menelepon:
Ini tentu saja akan gagal - jadi
IList<T>
tidak dapat ditandai kovarian.Ada juga, btw, opsi untuk
in
- yang digunakan oleh hal-hal seperti antarmuka perbandingan.IComparer<in T>
, misalnya, bekerja dengan cara yang berlawanan. Anda dapat menggunakan betonIComparer<Foo>
secara langsung sebagaiIComparer<Bar>
ifBar
adalah subclassFoo
, karenaIComparer<in T>
antarmuka bersifat contravariant .sumber
Image
adalah kelas abstrak;) Anda dapat melakukannyanew List<object>() { Image.FromFile("test.jpg") };
tanpa masalah, atau Anda dapat melakukannyanew List<object>() { new Bitmap("test.jpg") };
juga. Masalah dengan Anda adalah yangnew Image()
tidak diizinkan (Anda tidak dapat melakukanvar img = new Image();
keduanya)IList<object>
adalah contoh aneh, jika Anda mauobject
, Anda tidak perlu obat generik.Untuk mengingat dengan mudah penggunaan
in
danout
kata kunci (juga kovarian dan contravariance), kita dapat gambar pewarisan sebagai pembungkus:sumber
mempertimbangkan,
dan fungsinya,
Fungsi yang menerima
ICovariantSkinned<Fruit>
akan dapat menerimaICovariantSkinned<Fruit>
atauICovariantSkinned<Bananna>
karenaICovariantSkinned<T>
merupakan antarmuka kovarian danBanana
merupakan jenisFruit
,fungsi yang menerima
ISkinned<Fruit>
hanya akan dapat menerimaISkinned<Fruit>
.sumber
"
out T
" berarti tipeT
itu "kovarian". Itu membatasiT
muncul hanya sebagai nilai yang dikembalikan (keluar) dalam metode kelas generik, antarmuka atau metode. Implikasinya adalah Anda dapat menggunakan tipe / antarmuka / metode yang setara dengan tipe superT
.Misalnya
ICovariant<out Dog>
dapat dilemparkan keICovariant<Animal>
.sumber
out
penegakan yangT
dapat dikembalikan hanya, sampai saya membaca jawaban ini. Seluruh konsep lebih masuk akal sekarang!Dari tautan yang Anda poskan ....
EDIT : Sekali lagi, dari tautan yang Anda poskan
sumber