KeyValuePair gibi önceden oluşturulmuş bir yapı üzerinde 2 özellikli bir sınıfı ne zaman kullanmalıyım?


31

Anahtar / Değer türündeki verileri, a KeyValuePairveya a gibi önceden oluşturulmuş bir genel yapı kullanmak yerine kendi sınıfına ne zaman koymalısınız Tuple?

Örneğin, oluşturduğum ComboBox'ların çoğu bir DisplayName ve bir Değer içeriyor. Bu ne zaman yeni bir sınıfa ne zaman girileceğine ve bir KeyValuePair'i ne zaman kullanacağınıza karar vermeye çalıştığım veri türüdür.

Şu anda kullanan bir şey üzerinde çalışıyorum iCalendarve seçilen kullanıcının verileri nihayetinde bir key1=value1;key2=value2;dizgede birleşiyor. Verileri içine koyarak başladım KeyValuePair<string,string>, ama şimdi bunun bunun kendi sınıfı mı olması gerektiğini merak ediyorum.

Genel olarak, KeyValuePair2 özellikli bir nesne üzerindeki mevcut bir yapı / sınıfı kullanmaya karar verirken hangi kuralların kullanıldığını ve ne tür durumlarda bir başkasını kullanacağınızı öğrenmekle ilgileniyorum .


3
Hangi dil? Python'da bu ikilem yok, çünkü türümüz var tuple.
S.Lott

3
@ S.Lott - .NET BCL sürüm 4.0’dan bu yana sürümler
Oded

1
.NET 4 ayrıca, tuple türüne sahiptir. msdn.microsoft.com/en-us/library/system.tuple.aspx
Dave Nay

1
@Oded Bu durumda, bir şey inşa iCalendarediyorum BYDAYve ve için nesneler istedim BYSETPOS. ComboBox'larda görünürler, ancak gerçek veriler tekrarlanan kural dizgisinde birleştirilir, bu da bir key=value;dize türüdür
Rachel

4
@Rachel: Lütfen daha spesifik olması için soruyu güncelleyin . Bir sürü yorum bir şeyi açıklığa kavuşturmanın en iyi yolu değil.
S.Lott

Yanıtlar:


26

Genelde çoğu durumda bir KeyValuePair veya Tuple yerine bir nesne kullanırdım. Birincisi, değişiklik yapmak için 6 ay sonra geldiğinizde, neyin daha önce neyin Tuple tolduğunu ve neden bu komik değerlere sahip olduğunu merak etmek yerine niyetimizin ne olduğunu anlamak çok kolay değildir . İkincisi, işler büyüdükçe ve değiştikçe, basit veri aktarım nesnelerinize gereken şekilde kolayca davranabilirsiniz. İki isim formatına mı ihtiyacınız var? Kolay, sadece uygun ToString () aşırı yüklerini ekleyin. Bazı arayüzü uygulamak için ihtiyacınız var? Sorun değil. Son olarak, özellikle otomatik özelliklerde ve kod tamamlamada, basit bir nesne oluşturmak için neredeyse sıfır ek yük var.

Bonus Protip: Bu nesnelerin ad alanınızı kirletmesini önlemek istiyorsanız, sınıf içinde özel sınıflar yapmak, işleri tamamının altında tutmak ve garip bağımlılıkları önlemek için harika bir yoldur.


1
DTO'lar = Veri Aktarım Nesneleri ? - TLA'lardan nefret ediyorum ;-)
Ben

3
@Ben - TFTFY. . .
Wyatt Barnett

7

Yeni bir sınıf tanımlamanın kuralı basittir: “Occam's Razor” tarafından özetlenmiştir.

http://c2.com/cgi/wiki?OccamsRazor

İyi bir sebep olmadan yeni sınıflar tanıtmayın. Veya önceden oluşturulmuş sınıfları mümkün olduğunca kullanın. Veya mümkün olduğunca az icat. Ancak daha az kod yazarken rahatsınız.

Nesneye benzersiz bir sorumluluk vermek zorundaysanız ve bu sorumluluk önceden oluşturulmuş sınıfta tanımlanmamışsa, önceden oluşturulmuş bir sınıfı kullanamazsınız. Genellikle bu eşsiz bir yöntemdir.

A tupleveya KeyValuePairtercih edilir.

A kadar.

A tupleveya ' nın bir parçası olmayan bazı fonksiyonlara ihtiyacınız var KeyValuePair. O zaman kendi sınıfını tanımlaman gerekir.


3
" Asla çalabileceklerini asla tasarlama " Bu benim en sevdiğim ifade biçimiyle ilgili.
SingleNegationElimination

1
Eğer düşünür müsünüz anlamsal "bir parçası değil işlevsellik olmak tupleveya KeyValuePair"? KeyValuePair, en azından sınırlı bir anlam semantiğine sahiptir, ancak tuples nadiren (bağlama bağlı olarak mümkün olabilir) imho. Yeni bir sınıfa giriş, elbette mesele olarak size net bir anlam kazandırmalıdır.
Mal Ross,

+1 Bir fişe sığabilecekse, bir kanalı bant bantla bir bütün halinde yama yapmayın.
Evan Plaice,

4
Bence bu Occam'ın tıraş makinesinin yanlış kullanımı. İkincisi, bir değişkende hangi bilgilerin bulunduğunu bilmek önemlidir. -1.
Bent 12

4

Kendi sınıfınızı yazarsanız, iki değerin ne olduğuna dair belgeleri koymak için net bir yeriniz olur. Özellikle de iki tel çok net bir tanım olmadığı için. Ancak, gibi bir şey yazabilirsiniz

 public class MyPair : Tuple<string, string>

Bunu seviyorum çünkü MyPairTuple değerlerinin ne olduğunu ve ne için kullanıldığını tanımlar.
IA 13:11

2
Ama o zaman malların aranacak Item1ve Item2! Tüm sınıfı tanımlamak o kadar kolay değil mi? public class SideStrings { public string Left { get; set; } public string Right { get; set; } }
konfigüratör

@configurator Buna bir cevap yazıyordum ve Tuple'ın salt okunur olduğunu fark ettim, bu yüzden her şeyi kabul ettiğini düşünüyorum. Gerçi ne istersen değerleri adlandırmak için tuple sarabilirsin.
Burcu

2
@ İmzalı: Ama ne anlamı var? Kendi sınıfınızı oluşturmak, bir demet sarmaktan daha az iş demektir .
konfigüratör,

2
@configurator, özel bir nesneden daha iyi çalışan bazı eşitlik ve karşılaştırma öğelerine sahip olursunuz, ancak ayar gerekirse, sıralama kesinlikle yanlış yoldur.
İşareti

4

S.Lott yazdı

İyi bir sebep olmadan yeni sınıflar tanıtmayın. Veya önceden oluşturulmuş sınıfları mümkün olduğunca kullanın. Mümkün olduğunca az icat.

Önceden oluşturulmuş bir sınıfta tanımlanmayan nesneye benzersiz bir sorumluluk vermeniz gerekiyorsa, önceden oluşturulmuş bir sınıfı kullanamazsınız.

Neden bu konuda ciddi bir sorunum olduğunu söyleyeyim. Dan beri

KeyValuePair [string, string]

tamam gibi görünüyor .... KeyValue [string, KeyValue [string, KeyValuePair [string, string]]] de tamam mı? Ben S.Lott Buna ne der bilmiyorum ama patronum o düşünür olduğunu tamam.

Katılmıyorum cesaret. İşte bu yüzden: Takip edecek kodun Okunabilirliğini azaltır . Böyle bir veri yapısını dolduracaktır fonksiyonu çok daha karmaşık ve hata olacaktır (err .. istisna) eğilimli (sadece hayal en azından bazı iş mantığı yanı). Patronumla çok fazla tartışmadım, ama burada söyleyeceğim: Okunabilirlik, az yer kaplıyor (bu onun argümanıydı). Öyleyse, içinde bazı alanlar bulunan bir sınıf nesnesi olmaz; ama bazıları boş kalırken, bazen daha iyi olabilir mi?

PS Ben bir Ultra_Noob'um, bu yüzden lütfen yanılıyorsam bana söyle.


2
Bence KeyValuePair<string,string>, konulan şeylerin gerçekten anahtarlar ve değerler olduğunu varsayarsak. Burada, yazma kodunu kaydettiğiniz ve birlikte çalışabilirlik kazandığınız için mevcut bir sınıfı yeniden kullanmak bir kazançtır . OTOH, KeyValuePair<string,KeyValuePair<string,string>>çoğu zaman olduğu gibi karmaşık bir şey kullanarak, pratik olamayacak kadar karmaşık. Bazen doğru olabilir - ek bir işlevselliğe ihtiyaç duymadığınızda, anlam açıkken ve diğer sınıflarla iyi çalıştığında. YMMV, bu sadece artıları ve karşıtlıkları ağırlıklandırıyor.
maaartinus 13:11

C # kullanıyorsanız, işte Keyuple vs KeyValuePair'in performansları . Patronunla paylaşmak isteyebileceğin bir şey mi var?
Ben

3

Biz derken anahtar / değer çiftini, genellikle düşünüyorum karma tabloları veya ilişkilendirilebilir dizilerle , ya da sadece bir KeyValuePair nesnesi. Hepsini kullanıyorum ve hangisini kullandığımda hiçbir fark yok.

Anahtar / değer çiftlerinin bir listesiyle ilgili en önemli şey, anahtarların benzersiz olması gerektiği (çünkü hepsinden önce bir anahtardır) ve yukarıda belirtilen yapıların hepsi bana gerçekten bu işlevselliği sağlar.

Bunun dışında, tuşlarla arama yapmak veya push ve pop gibi liste (dizi) tarzı eylemler yapmak istiyorum.

Bu yüzden cevabım HAYIR ve anahtar / değer çiftleri için açıkça nesneler yaratmıyorum, çünkü birçok yerleşik yapı zaten benim için bunu yapıyor.


3

Temiz Kod'un altıncı bölümünde , bir sınıfa karşı veri yapısının ne zaman kullanılacağına ilişkin iyi bir açıklama vardır. Özet olarak, bu veriler üzerinde çalışmak için çoğunlukla yeni işlevler eklemeyi düşündüğünüzde bir veri yapısı kullanırsınız. Var olan işlevler tarafından çalıştırılacak yeni veri türleri eklemeyi düşündüğünüzde bir sınıf kullanırsınız. ComboBox'unuz ikincisinin bir örneğidir. Birçok farklı veri türünde (farklı widget'ler için farklı veri türleri) çalışan bir işlev kümeniz (ComboBox uygulaması) vardır.


2

Belki de burada Wilding ile aynı fikirdeyim , ama o zaman ben de böyle bir işte biraz noob.

Yerleşik türlerin genellikle mekanizma nesneleri olduğunu öneriyorum . Örneğin, KeyValuePair, benzersiz anahtarların sağlanmasına yardımcı olan bir sözlük ve karma tabloların mekanizmasının bir parçasıdır ve mekanizmanın kendi içinde anlamlı isimlere sahip özelliklere sahiptir.

Öte yandan, ısmarlama veri nesnelerini kullanmak, verilerinizin daha iyi temsil edilmesini sağlar ve okunabilirlik ve genişletilebilirlik dahil olmak üzere birçok fayda sağlar. Özel olarak oluşturulmuş nesnelerde var olan kodu Yeniden İşaret önerildiği şekilde yeniden kullanmayı durduracak hiçbir şey yok , ancak sarılmış sınıfı gizlemeye çalışacağım ve soyutlama sızıntısından kaçınacağım için , altta yatan uygulamayı kodunuzun geri kalanını etkilemeden daha sonra değiştirebileceksiniz. .

Öyleyse asıl soru: Verileri temsil ediyor musunuz yoksa verileri bir mekanizmada mı kullanıyorsunuz? (ve bu kavramları birlikte karıştırmanızı tavsiye etmem).

Tecrübelerime göre, bir Tuple [string, string] 'nin bir metoda iletildiğini ve Item1 ve Item2'nin ne olması gerektiğini bilmenin hemen bir yolunun bulunmadığını daha kötü bir şey yoktur. Tuples'i yöntemler içinde veya yalnızca bir sınıfın özel üyeleri olarak kullanmak en iyisidir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.