Saya baru saja menemukan ArraySegment<byte>
tipe saat membuat subclass MessageEncoder
kelas.
Sekarang saya mengerti bahwa itu adalah segmen dari larik yang diberikan, mengambil offset, tidak dapat dihitung, dan tidak memiliki pengindeks, tetapi saya masih gagal memahami penggunaannya. Bisakah seseorang menjelaskan dengan sebuah contoh?
ArraySegment
dapat dihitung dalam .Net 4.5.Jawaban:
ArraySegment<T>
telah menjadi jauh lebih berguna di .NET 4.5 + dan .NET Core karena sekarang diimplementasikan:IList<T>
ICollection<T>
IEnumerable<T>
IEnumerable
IReadOnlyList<T>
IReadOnlyCollection<T>
berlawanan dengan versi .NET 4 yang tidak menerapkan antarmuka apa pun.
Kelas sekarang dapat mengambil bagian dalam dunia LINQ yang menakjubkan sehingga kita dapat melakukan hal-hal LINQ yang biasa seperti meminta konten, membalikkan konten tanpa memengaruhi larik asli, mendapatkan item pertama, dan seterusnya:
sumber
GetEnumerator
pribadi, artinya Anda terpaksa melakukanIEnumerable<T>
(konversi tinju) untuk menyebutnya. Ugh!Dalam contoh ini, kita melihat bagaimana Anda dapat menggunakan array asli, properti Offset dan Count, dan juga bagaimana Anda dapat melakukan loop melalui elemen yang ditentukan dalam ArraySegment.
Struktur ArraySegment - apa yang mereka pikirkan?
sumber
i < segment.Offset + segment.Count
.Ini adalah struct prajurit kecil yang lemah yang tidak melakukan apa pun selain menyimpan referensi ke array dan menyimpan rentang indeks. Sedikit berbahaya, berhati-hatilah karena ini tidak membuat salinan data larik dan tidak dengan cara apa pun membuat larik tidak dapat diubah atau menyatakan kebutuhan akan kekekalan. Pola pemrograman yang lebih umum adalah dengan hanya menyimpan atau meneruskan array dan variabel panjang atau parameter, seperti yang dilakukan dalam metode .NET BeginRead (), String.SubString (), Encoding.GetString (), dll, dll.
Itu tidak banyak digunakan di dalam .NET Framework, kecuali untuk apa yang tampak seperti salah satu pemrogram Microsoft tertentu yang bekerja pada soket web dan WCF menyukainya. Yang mungkin panduan yang tepat, jika Anda suka maka gunakanlah. Itu melakukan peek-a-boo di .NET 4.6, metode MemoryStream.TryGetBuffer () yang ditambahkan menggunakannya. Lebih disukai daripada memiliki dua
out
argumen yang saya asumsikan.Secara umum, pengertian slice yang lebih universal ada di daftar keinginan para engineer .NET utama seperti Mads Torgersen dan Stephen Toub. Yang terakhir memulai
array[:]
proposal sintaks beberapa waktu yang lalu, Anda dapat melihat apa yang mereka pikirkan di halaman Roslyn ini . Saya berasumsi bahwa mendapatkan dukungan CLR adalah apa yang akhirnya bergantung pada hal ini. Ini sedang dipikirkan secara aktif untuk C # versi 7 afaik, awasi System.Slices .Pembaruan: tautan mati, ini dikirim dalam versi 7.2 sebagai Span .
Update2: lebih banyak dukungan dalam C # versi 8.0 dengan tipe Range dan Index dan metode Slice ().
sumber
Bagaimana dengan kelas pembungkus? Hanya untuk menghindari menyalin data ke buffer sementara.
Contoh:
Ouput:
sumber
IEnumerable<T>
kemudian menambahkan IEnumeratorIEnumerable.GetEnumerator() { return GetEnumerator(); }
ArraySegment JAUH lebih berguna dari yang Anda kira. Coba jalankan unit test berikut dan bersiaplah untuk kagum!
Soalnya, yang harus Anda lakukan adalah melemparkan ArraySegment ke IList dan itu akan melakukan semua hal yang mungkin Anda harapkan dari awalnya. Perhatikan bahwa tipenya masih ArraySegment, meskipun berperilaku seperti daftar normal.
KELUARAN:
sumber
IList<T>
. Saya berharap pengindeks akan menjadipublic
.Dengan kata sederhana: ini menyimpan referensi ke sebuah array, memungkinkan Anda memiliki banyak referensi ke satu variabel array, masing-masing dengan rentang yang berbeda.
Sebenarnya ini membantu Anda untuk menggunakan dan melewatkan bagian dari sebuah array dengan cara yang lebih terstruktur, daripada memiliki banyak variabel, untuk menahan indeks awal dan panjang. Juga menyediakan antarmuka koleksi untuk bekerja lebih mudah dengan bagian array.
Misalnya, dua contoh kode berikut melakukan hal yang sama, satu dengan ArraySegment dan satu tanpa:
dan,
Jelas potongan kode pertama lebih disukai, khususnya ketika Anda ingin meneruskan segmen array ke suatu fungsi.
sumber