Quando dovrei usare una classe di proprietà a 2 su una struttura pre-costruita come KeyValuePair?

30

Quando dovresti inserire il tipo di dati Key / Value nella propria classe invece di usare una struttura generica pre-costruita, come KeyValuePair o Tuple ?

Ad esempio, la maggior parte dei ComboBox che ho creato contengono un DisplayName e un Valore. Questo è il tipo di dati che sto cercando di decidere quando inserire una nuova classe e quando usare solo KeyValuePair.

Attualmente sto lavorando a qualcosa che utilizza iCalendar , e i dati dell'utente selezionato vengono infine combinati in un tipo di stringa key1=value1;key2=value2; . Ho iniziato inserendo i dati in un KeyValuePair<string,string> , ma ora mi chiedo se dovrebbe essere invece la classe.

Nel complesso, sono interessato a scoprire quali linee guida vengono utilizzate quando si decide di utilizzare una struttura / classe esistente come KeyValuePair su un oggetto con proprietà 2 e in quale tipo di situazioni si utilizzerebbe l'una sull'altra.

    
posta Rachel 13.09.2011 - 15:29
fonte

7 risposte

25

Normalmente utilizzerei un oggetto piuttosto che un KeyValuePair o una tupla nella maggior parte dei casi. Innanzitutto, quando sei arrivato 6 mesi dopo per apportare modifiche, è molto più facile capire quale fosse il tuo intento prima piuttosto che chiedermi cosa sia Tuple t e perché ha quei valori divertenti. In secondo luogo, mentre le cose crescono e cambiano, puoi facilmente dare il tuo semplice comportamento agli oggetti di trasferimento dei dati come richiesto. Hai bisogno di avere due formati di nome? Semplice, basta aggiungere gli overload ToString () appropriati. Serve per implementare qualche interfaccia? Nessun problema. Infine, c'è davvero un sovraccarico quasi zero nella creazione di un oggetto semplice, specialmente con proprietà automatiche e completamento del codice.

Bonus Protip: se vuoi impedire a questi oggetti di inquinare il tuo spazio dei nomi, creare classi private all'interno delle classi è un ottimo modo per tenere le cose sotto controllo ed evitare strane dipendenze.

    
risposta data 13.09.2011 - 16:10
fonte
7

La regola per definire una nuova classe è semplice: è sintetizzata da "Rasoio di Occam".

link

Non introdurre nuove classi senza una buona ragione. O utilizzare le classi pre-costruite il più possibile. Oppure inventare il meno possibile. Comunque sei a tuo agio a scrivere meno codice.

Non è possibile utilizzare una classe precostruita se è necessario assegnare una responsabilità esclusiva all'oggetto e tale responsabilità non è definita nella classe precostruita. Spesso questo è un metodo unico.

È preferito un tuple o KeyValuePair .

Fino.

Hai bisogno di alcune funzionalità che non fanno parte di A tuple o KeyValuePair . Quindi devi definire la tua classe.

    
risposta data 13.09.2011 - 16:46
fonte
4

Se scrivi la tua classe, hai un posto libero dove mettere la documentazione su quali sono i due valori. Soprattutto dal momento che due stringhe non è una definizione molto chiara. Comunque potresti scrivere qualcosa come

 public class MyPair : Tuple<string, string>
    
risposta data 13.09.2011 - 16:29
fonte
4

S.Lott ha scritto

Do not introduce new classes without a good reason. Or use pre-built classes as much as possible. Invent as little as possible.

You cannot use a pre-built class if you have to assign some unique responsibility to the object that is not defined in the pre-built class.

Lasciami dire perché ho un problema serio con questo. Poiché

KeyValuePair [string,string]

sembra essere ok ... è KeyValue [string, KeyValue [string, KeyValuePair [string, string]]] ok? Non so cosa dirà S.Lott a questo, ma il mio capo pensa che sia ok.

Oserei non essere d'accordo. Ed ecco perché: riduce Readability del codice che seguirà. La funzione che riempirà una tale struttura di dati sarà molto più complessa e l'errore (err .. eccezionalmente) incline (basta immaginare almeno qualche logica di business pure). Non ho litigato troppo con il mio capo, ma lo dirò qui: la leggibilità supera il risparmio di spazio (che era il suo argomento ). Quindi non sarebbe un oggetto di classe in cui ci sono alcuni campi; ma alcuni rimangono vuoti, a volte vanno meglio?

P.S. Sono un Ultra_Noob quindi per favore dimmi se sbaglio.

    
risposta data 13.09.2011 - 21:31
fonte
3

Quando diciamo la coppia chiave / valore , di solito penso alle tabelle hash o agli array associativi o semplicemente a KeyValuePair oggetto. Li uso tutti e non c'è differenza in quando uso quale.

Penso che la cosa più importante di un elenco di coppie chiave / valore sia che, le chiavi dovrebbero essere uniche (poiché dopotutto è una chiave) e tutte le strutture sopra citate mi forniscono davvero quella funzionalità.

Oltre a questo, voglio cercare per chiavi, o per fare azioni in stile lista (array) come push e pop.

Quindi, la mia risposta è, NO , e non creo oggetti esplicitamente per coppie chiave / valore, dal momento che molte strutture built-in lo fanno già per me.

    
risposta data 13.09.2011 - 15:47
fonte
3

Il capitolo 6 di Pulisci codice ha una buona descrizione di quando utilizzare una struttura dati rispetto a una classe. In poche parole, si utilizza una struttura dati quando si prevede di aggiungere nuove funzioni per operare su tali dati. Utilizzi un corso quando prevedi principalmente di aggiungere nuovi tipi di dati che devono essere gestiti da funzioni esistenti. Il tuo ComboBox è un esempio di quest'ultimo. Hai un set di funzioni (l'implementazione ComboBox) che operano su molti tipi di dati diversi (diversi tipi di dati per diversi widget).

    
risposta data 13.09.2011 - 16:23
fonte
2

Sarei forse d'accordo con Wilding qui , ma poi sono un po 'un noob in questo tipo di cosa troppo.

Suggerirei che i tipi built-in siano spesso oggetti meccanismo . KeyValuePair, ad esempio, fa parte del meccanismo di un dizionario e tabelle hash, contribuendo a garantire chiavi univoche e hanno proprietà che hanno nomi significativi all'interno del contesto del meccanismo stesso.

D'altra parte, l'utilizzo di oggetti dati personalizzati fornisce una rappresentazione dei tuoi dati e offre numerosi vantaggi, tra cui la leggibilità e l'estensibilità. Non c'è nulla da fare per impedire il riutilizzo del codice esistente negli oggetti personalizzati come Segnalazione suggerita , ma proverei a nascondere l'involucro classe ed evita perdita di astrazione , in modo da poter cambiare l'implementazione sottostante in un secondo momento senza influire sul resto del codice .

Quindi la vera domanda: Stai rappresentando i dati o stai utilizzando i dati in un meccanismo? (e non consiglierei di unire questi concetti insieme).

Nella mia esperienza non c'è niente di peggio che vedere una Tupla [stringa, stringa] essere passata in un metodo e non avere alcun modo immediato per sapere cosa dovrebbero essere Item1 e Item2. Meglio usare Tuples all'interno dei metodi o solo come membri privati di una classe.

    
risposta data 07.06.2015 - 17:34
fonte

Leggi altre domande sui tag