Devo evitare raccolte generiche nidificate?

0

Recentemente ho trovato un dizionario con elenchi di valori passati come argomento:

Demo(Dictionary<string, List<string>> arg)

Mi ha fatto pensare --- normalmente vorrei astrarre qualsiasi elenco o array a un oggetto IEnumerable con lo stesso tipo di elemento. Allo stesso modo, un dizionario specifico potrebbe essere astratto a IDictionary. Ma una costruzione annidata, per quanto ne so, non può essere astratta, in quanto è incerta in termini di varianza e non può essere castata a:

IDictionary<string, <IEnumerable<string>>

Ci sono altri motivi per evitare i generici annidati? O li sto usando male? Questo caso d'uso garantisce una classe separata?

    
posta Heagon 26.09.2018 - 07:19
fonte

1 risposta

0

Probabilmente

Ci sono diversi casi d'uso e diverse scuole di pensiero nella programmazione.

Tuttavia, dalla mia esperienza, non mi sono mai pentito di aver inserito una raccolta di cose nella sua classe . Ti consente di limitare l'accesso nel modo in cui la raccolta è destinata a essere utilizzata, inoltre puoi nominare quei "punti di accesso" (= metodi, proprietà ecc.).

Perché non solo LINQ

Certo, con LINQ puoi facilmente filtrare, ordinare, rimuovere tutti gli elementi che hanno la condizione x ecc., ma se crei una classe contenente la raccolta ( private -ly), puoi limitare la classe a fare solo una certo modo. Ad esempio, puoi fornire un metodo standard di filtraggio. Questo è fondamentalmente il concetto OOP di incapsulamento .

Encapsulation is an object-oriented programming concept that binds together the data and functions that manipulate the data, and that keeps both safe from outside interference and misuse.

A proposito, non sto sostenendo contro LINQ, perché è sorprendente. Le query LINQ tendono a finire in un metodo sulle mie "classi di raccolta" e assomigliano molto a cosa consiglia Martin Fowler in questo Per quanto riguarda . È un lungo articolo, ma il primo esempio è sufficiente per dimostrare cosa intendo:

static public IEnumerable<String> TwitterHandles(IEnumerable<Author> authors, string company) {
return authors
  .Where(a => a.Company == company)
  .Select(a => a.TwitterHandle)
  .Where (h => h != null);
}

Consigli: incapsula le raccolte

Essenzialmente, una propria classe ArgumentList può fornire funzionalità aggiuntive, mentre non ci vuole nulla. Qualunque cosa tu intenda usare, puoi esporre - qualunque cosa tu non intenda usare non puoi essere usata.

Questo significa anche che ora devi preoccuparti solo della interfaccia di ArgumentList e non della sua implementazione . Ho avuto la mia giusta dose di casi in cui una tale "classe di raccolta" ha reso evidente che in realtà non ho bisogno di un Dictionary<> e un List<> è stato sufficiente. Inoltre, è stato anche facile cambiarlo in List<> perché avevo solo bisogno di cambiare la classe di raccolta stessa - basta sostituire la raccolta e regolare il codice nei metodi in modo che facciano comunque quello che dicono.

Ora come riassunto di tutto ciò, IDictionary<string, ArgumentList> è migliore del tuo esempio dato, ma in un certo senso è solo un sintomo di qualcosa di più grande .

PS

Detto questo, ho una parte nella mia attuale base di codice che usa collezioni simili al tuo esempio. Perché è "solo spostando alcuni dati finché non si adatta". Comunque, in ogni altro posto in cui ho usato una "collection class", il codice è molto più facile da capire e sto considerando di cambiare anche questa parte. Sai, quando ho il tempo : D

Inoltre, nel caso si utilizzino contenitori IoC, le "classi di raccolta" sono più facili da usare rispetto alle raccolte bare-bone.

Ti suggerisco di leggere la domanda e la risposta accettata qui . Non è un duplicato o una domanda simile, ma la risposta accettata ha una certa sovrapposizione di informazioni. È una spiegazione molto bella di come le collezioni siano pensate per essere utilizzate in C #, da uno dei creatori di C # non meno - è stato sicuramente un po 'un momento per me.

    
risposta data 26.09.2018 - 12:14
fonte

Leggi altre domande sui tag