Kapan Anda harus memasukkan tipe data Key / Value di kelasnya sendiri alih-alih menggunakan struktur generik pra-bangun, seperti a KeyValuePair
atau a Tuple
?
Misalnya, sebagian besar Kotak Kombo yang saya buat mengandung DisplayName dan Nilai. Ini adalah jenis data yang saya coba putuskan kapan akan dimasukkan ke kelas baru, dan kapan harus menggunakan KeyValuePair.
Saat ini saya sedang mengerjakan sesuatu yang menggunakan iCalendar
, dan data pengguna yang dipilih akhirnya digabungkan menjadi key1=value1;key2=value2;
sejenis string. Saya mulai dengan memasukkan data ke dalam KeyValuePair<string,string>
, tetapi sekarang saya bertanya-tanya apakah itu seharusnya kelas itu sendiri.
Secara keseluruhan, saya tertarik untuk mencari tahu pedoman apa yang digunakan ketika memutuskan untuk menggunakan struktur / kelas yang sudah ada seperti objek KeyValuePair
lebih dari 2 properti, dan dalam situasi apa Anda akan menggunakan satu sama lain.
sumber
tuple
tipe.iCalendar
dan saya ingin benda untukBYDAY
danBYSETPOS
. Mereka muncul di ComboBoxes, tetapi data aktual digabungkan ke dalam string aturan berulang, yang merupakankey=value;
jenis stringJawaban:
Saya biasanya menggunakan objek daripada KeyValuePair atau Tuple dalam banyak kasus. Pertama, ketika Anda datang dalam 6 bulan kemudian untuk melakukan perubahan, jauh lebih mudah untuk mengetahui apa maksud Anda lebih awal daripada bertanya-tanya apa
Tuple t
itu dan mengapa ia memiliki nilai-nilai lucu itu. Kedua, seiring pertumbuhan dan perubahan, Anda dapat dengan mudah memberikan perilaku objek transfer data sederhana sesuai kebutuhan. Perlu memiliki dua format nama? Mudah, tambahkan saja kelebihan ToString (). Perlu untuk mengimplementasikan beberapa antarmuka? Tidak masalah. Akhirnya, hampir tidak ada overhead untuk membuat objek sederhana, terutama dengan properti otomatis dan penyelesaian kode.Bonus Protip: jika Anda ingin menjaga benda-benda ini dari mencemari namespace Anda, membuat kelas privat di dalam kelas adalah cara yang bagus untuk menjaga hal-hal tetap tersembunyi dan mencegah ketergantungan aneh.
sumber
Aturan untuk mendefinisikan kelas baru adalah sederhana: Ini dirangkum oleh "Occam's Razor".
http://c2.com/cgi/wiki?OccamsRazor
Jangan memperkenalkan kelas baru tanpa alasan yang bagus. Atau gunakan kelas pra-bangun sebanyak mungkin. Atau ciptakan sesedikit mungkin. Namun Anda merasa nyaman menulis lebih sedikit kode.
Anda tidak dapat menggunakan kelas pra-dibangun jika Anda harus menetapkan beberapa tanggung jawab unik untuk objek dan tanggung jawab itu tidak didefinisikan dalam kelas pra-dibangun. Seringkali ini adalah metode yang unik.
A
tuple
atauKeyValuePair
lebih disukai.Sampai.
Anda memerlukan beberapa fungsionalitas yang bukan bagian dari A
tuple
atauKeyValuePair
. Maka Anda harus mendefinisikan kelas Anda sendiri.sumber
tuple
atauKeyValuePair
"? KeyValuePair setidaknya memiliki beberapa bentuk semantik, tetapi tuple jarang melakukannya (mungkin, tergantung pada konteks) imho. Memperkenalkan kelas baru seharusnya memberi Anda semantik yang jelas sebagai hal yang biasa.Jika Anda menulis kelas Anda sendiri, Anda memiliki tempat yang jelas untuk meletakkan dokumentasi tentang apa kedua nilai tersebut. Terutama karena dua string bukanlah definisi yang sangat jelas. Namun Anda dapat menulis sesuatu seperti
sumber
MyPair
mendefinisikan apa nilai Tuple dan untuk apa mereka digunakan.Item1
danItem2
! Bukankah semudah mendefinisikan seluruh kelas?public class SideStrings { public string Left { get; set; } public string Right { get; set; } }
S.Lott menulis
Biarkan saya mengatakan mengapa saya memiliki masalah serius dengan ini. Sejak
tampaknya baik-baik saja .... apakah KeyValue [string, KeyValue [string, KeyValuePair [string, string]]] juga oke? Aku tidak tahu apa S. Lott akan mengatakan ini, tapi bos saya berpikir itu adalah apa apa.
Saya berani tidak setuju. Dan inilah alasannya: Ini mengurangi keterbacaan kode yang akan mengikuti. Fungsi yang akan mengisi struktur data seperti itu akan jauh lebih kompleks dan kesalahan (err .. pengecualian) cenderung (bayangkan setidaknya beberapa logika bisnis juga). Saya tidak berdebat dengan bos saya terlalu banyak, tapi aku akan mengatakan di sini: Keterbacaan mengalahkan penghematan ruang menit (yang nya argumen). Jadi tidak akan objek kelas di mana ada beberapa bidang; tetapi beberapa tetap kosong pada beberapa waktu menjadi lebih baik?
PS Saya seorang Ultra_Noob jadi tolong beri tahu saya jika saya salah.
sumber
KeyValuePair<string,string>
baik-baik saja, dengan asumsi hal-hal yang dimasukkan memang kunci dan nilai. Di sini, menggunakan kembali kelas yang ada adalah kemenangan, karena Anda menyimpan kode penulisan dan mendapatkan interoperabilitas. OTOH, menggunakan sesuatu yang rumit sepertiKeyValuePair<string,KeyValuePair<string,string>>
kebanyakan waktu terlalu rumit untuk praktis. Kadang-kadang mungkin benar - ketika Anda tidak memerlukan fungsionalitas tambahan, ketika artinya jelas, dan ketika itu berfungsi dengan baik dengan kelas lain. YMMV, ini hanya menimbang pro dan kontra.Ketika kita mengatakan pasangan kunci / nilai , saya biasanya memikirkan tabel hash , atau array asosiatif , atau hanya KeyValuePair objek . Saya menggunakan semuanya dan tidak ada perbedaan kapan saya menggunakannya.
Saya pikir yang paling penting tentang daftar pasangan kunci / nilai adalah, kunci harus unik (karena ini memang kunci), dan semua struktur yang disebutkan di atas benar-benar memberi saya fungsionalitas itu.
Selain itu, saya ingin mencari berdasarkan tombol, atau melakukan tindakan gaya daftar (larik) seperti push dan pop.
Jadi, jawaban saya adalah, TIDAK , dan saya tidak membuat objek secara eksplisit untuk pasangan kunci / nilai, karena banyak struktur bawaan sudah melakukan itu untuk saya.
sumber
Bab enam dari Kode Bersih memiliki deskripsi yang baik tentang kapan harus menggunakan struktur data versus kelas. Singkatnya, Anda menggunakan struktur data ketika Anda sebagian besar mengantisipasi menambahkan fungsi baru untuk beroperasi pada data itu. Anda menggunakan kelas saat Anda sebagian besar mengantisipasi menambahkan tipe data baru untuk dioperasikan oleh fungsi yang ada. ComboBox Anda adalah contoh dari yang terakhir. Anda memiliki satu set fungsi (implementasi ComboBox) yang beroperasi pada banyak tipe data yang berbeda (berbagai jenis data untuk widget yang berbeda).
sumber
Saya mungkin akan setuju dengan Wilding di sini , tapi kemudian saya sedikit noob di hal semacam ini juga.
Saya akan menyarankan bahwa tipe built-in sering merupakan objek mekanisme . KeyValuePair misalnya, adalah bagian dari mekanisme kamus dan tabel hash, membantu memastikan kunci unik dan mereka memiliki properti yang memiliki nama yang bermakna dalam konteks mekanisme itu sendiri.
Di sisi lain, menggunakan objek data yang dibuat khusus memberikan representasi yang lebih baik dari data Anda dan memberikan banyak manfaat, termasuk keterbacaan dan ekstensibilitas. Tidak ada yang berhenti menggunakan kembali kode yang ada di objek yang dibuat khusus seperti yang disarankan Masuk , tapi saya akan mencoba dan menyembunyikan kelas yang dibungkus, dan menghindari kebocoran abstraksi , sehingga Anda dapat mengubah implementasi yang mendasarinya di titik kemudian tanpa mempengaruhi sisa kode Anda .
Jadi pertanyaan sebenarnya: Apakah Anda mewakili data atau Anda menggunakan data dalam suatu mekanisme? (dan saya tidak akan menyarankan menggabungkan konsep-konsep ini bersama-sama).
Dalam pengalaman saya, tidak ada yang lebih buruk dari melihat [string, string] Tuple dilewatkan ke dalam metode dan tidak memiliki cara langsung untuk mengetahui apa yang seharusnya menjadi Item1 dan Item2. Terbaik untuk menggunakan Tuples dalam metode atau sebagai anggota pribadi kelas saja.
sumber