Saya memiliki array X dari 10 elemen. Saya ingin membuat array baru yang berisi semua elemen dari X yang dimulai pada indeks 3 dan berakhir pada indeks 7. Tentu saya dapat dengan mudah menulis sebuah loop yang akan melakukannya untuk saya, tetapi saya ingin menjaga kode saya sebersih mungkin . Apakah ada metode dalam C # yang dapat melakukannya untuk saya?
Sesuatu seperti (kode semu):
Array NewArray = oldArray.createNewArrayFromRange(int BeginIndex , int EndIndex)
Array.Copy
tidak sesuai dengan kebutuhan saya . Saya perlu item dalam array baru menjadi klon. Array.copy
hanya memcpy
setara dengan C-Style , bukan itu yang saya cari.
Jawaban:
Anda dapat menambahkannya sebagai metode ekstensi:
Perbarui kembali kloning (yang tidak jelas dalam pertanyaan asli). Jika Anda benar - benar menginginkan klon yang dalam; sesuatu seperti:
Ini memang membutuhkan objek yang dapat serial (
[Serializable]
atauISerializable
). Anda bisa dengan mudah mengganti untuk setiap serializer lain yang sesuai -XmlSerializer
,DataContractSerializer
, protobuf-net, dllPerhatikan bahwa klon dalam sulit tanpa serialisasi; khususnya,
ICloneable
sulit dipercaya dalam banyak kasus.sumber
Anda dapat menggunakannya
Array.Copy(...)
untuk menyalin ke array baru setelah Anda membuatnya, tapi saya rasa tidak ada metode yang menciptakan array baru dan menyalin berbagai elemen.Jika Anda menggunakan .NET 3.5 Anda bisa menggunakan LINQ:
tapi itu akan menjadi kurang efisien.
Lihat jawaban ini untuk pertanyaan serupa untuk opsi untuk situasi yang lebih spesifik.
sumber
Sudahkah Anda mempertimbangkan untuk menggunakan
ArraySegment
?http://msdn.microsoft.com/en-us/library/1hsbd92d.aspx
sumber
IEnumerable<T>
dan berbagai antarmuka yang berguna lainnya.ArraySegment
untuk menjawab pertanyaan awal?IList<T> newArray = (IList<T>)new ArraySegment<T>(oldArray, beginIndex, endIndex);
Saya melihat Anda ingin melakukan Kloning, bukan hanya menyalin referensi. Dalam hal ini Anda dapat menggunakan
.Select
untuk memproyeksikan anggota array ke klonnya. Misalnya, jika elemenIClonable
Anda diimplementasikan, Anda dapat melakukan sesuatu seperti ini:Catatan: Solusi ini membutuhkan .NET Framework 3.5.
sumber
IEnumerable
. Saya bisa mendapatkanIEnumerable
,IList
,IArray
, dll ... dengan sedikit rewel, inline jika saya perlu. Jika saya tidak membutuhkan salinan yang dalam, saya hanya menghapusSelect
. MenjatuhkanSkip
atauTake
memungkinkan saya untuk mengontrol rentang. Atau, saya bisa mencampurnya denganSkipWhile
dan / atauTakeWhile
.Kode berikut melakukannya dalam satu baris:
sumber
Di C # 8 mereka sudah memperkenalkan yang baru
Range
danIndex
ketiksumber
sumber
Membangun jawaban Marc tetapi menambahkan perilaku kloning yang diinginkan
Dan jika menerapkan ICloneable terlalu banyak seperti kerja keras yang reflektif menggunakan perpustakaan Håvard Stranden Copyable untuk melakukan pengangkatan berat yang diperlukan.
Perhatikan bahwa implementasi OX.Copyable berfungsi dengan salah satu dari:
Jadi ini harus mencakup hampir semua situasi yang Anda miliki. Jika Anda mengkloning objek di mana sub grafik berisi hal-hal seperti koneksi db atau file / stream menangani Anda jelas memiliki masalah tetapi itu berlaku untuk setiap salinan yang digeneralisasi secara umum.
Jika Anda ingin menggunakan beberapa pendekatan penyalinan dalam, artikel ini mencantumkan beberapa yang lain, jadi saya sarankan untuk tidak mencoba menulis sendiri.
sumber
Anda dapat melakukan ini dengan cukup mudah;
sumber
Saya pikir kode yang Anda cari adalah:
Array.Copy(oldArray, 0, newArray, BeginIndex, EndIndex - BeginIndex)
sumber
Sebagai alternatif untuk menyalin data Anda bisa membuat pembungkus yang memberi Anda akses ke bagian dari array asli seolah-olah itu adalah salinan dari bagian array. Keuntungannya adalah Anda tidak mendapatkan salinan data lainnya dalam memori, dan kekurangannya adalah sedikit overhead saat mengakses data.
Pemakaian:
sumber
Array.ConstrainedCopy akan berfungsi.
sumber
Tidak ada metode tunggal yang akan melakukan apa yang Anda inginkan. Anda perlu membuat metode klon tersedia untuk kelas dalam array Anda. Kemudian, jika LINQ adalah opsi:
sumber
Bagaimana dengan menggunakan Array.ConstrainedCopy :
Di bawah ini adalah posting asli saya. Itu tidak akan bekerja
Anda dapat menggunakan Array.CopyTo :
sumber
Bagaimana dengan ini:
Anda kemudian perlu mengimplementasikan antarmuka ICloneable di semua kelas yang Anda perlu gunakan ini tetapi itu harus dilakukan.
sumber
Saya tidak yakin seberapa dalam itu sebenarnya, tetapi:
MyArray.ToList<TSource>().GetRange(beginningIndex, endIndex).ToArray()
Ini sedikit overhead, tetapi mungkin memotong metode yang tidak perlu.
sumber
C # 8 telah menyediakan fitur yang disebut Range untuk mendapatkan subarry dari indeks awal hingga akhir. Anda bisa menggunakannya seperti ini.
sumber
Sejauh kloning berjalan, saya tidak berpikir serialisasi memanggil konstruktor Anda. Ini dapat merusak invarian kelas jika Anda melakukan hal-hal menarik di ctor's.
Tampaknya taruhan yang lebih aman adalah metode klon virtual yang memanggil copy constructor.
sumber
Elemen kloning dalam array bukanlah sesuatu yang bisa dilakukan secara universal. Apakah Anda ingin kloning mendalam atau salinan sederhana dari semua anggota?
Mari kita pergi untuk pendekatan "upaya terbaik": objek kloning menggunakan antarmuka ICloneable atau serialisasi biner:
Ini bukan solusi yang sempurna, karena tidak ada satu pun yang akan bekerja untuk semua jenis objek.
sumber
Anda dapat mengambil kelas yang dibuat oleh Microsoft:
lalu
sumber
Ini adalah cara optimal, saya temukan, untuk melakukan ini:
Semoga Itu Membantu!
sumber
gunakan metode extention:
dan kamu bisa menggunakannya
sumber
Kode dari System.Private.CoreLib.dll:
sumber
Itu tidak memenuhi persyaratan kloning Anda, tetapi tampaknya lebih sederhana daripada banyak jawaban untuk dilakukan:
sumber
sumber