2009-05-28 9 views
6

Seguendo i suggerimenti di FxCop e la mia inclinazione personale ho incoraggiato il team che sto preparando a utilizzare ReadOnlyCollections il più possibile. Se solo così i destinatari degli elenchi non possono modificare il loro contenuto. Nella loro teoria questo è il pane & burro. Il problema è che l'interfaccia Elenco < è molto più ricca esponendo tutti i tipi di metodi utili. Perché hanno fatto quella scelta?Perché ReadOnlyCollection <> non include metodi come FindAll(), FindFirst(),

Ti arrendi e restituisci raccolte scrivibili? Ritorni raccolte di sola lettura e poi le avvolgi nella varietà scrivibile? Ahhhhh.


Update: Grazie ho familiarità con il quadro di design linee guida e questo è il motivo per cui il team sta usando FxCop di farla rispettare. Comunque questa squadra vive con VS 2005 (lo so, lo so) e così dicendo che i metodi LINQ/Extension risolverebbero i loro problemi li rende solo tristi.

Hanno appreso che List.FindAll() e .FindFirst() forniscono maggiore chiarezza rispetto alla scrittura di un ciclo foreach. Ora li sto spingendo a usare ReadOnlyCollections per perdere quella chiarezza.

Forse c'è un problema di progettazione più profondo che non sto individuando.

- Spiacente, il post originale avrebbe dovuto menzionare la limitazione VS2005. Ho vissuto per così tanto tempo che non me ne accorgo.

risposta

6

sezione 8.3.2 della .NET Framework Design Guidelines Second Edition:

DO uso ReadOnlyCollection<T>, una sottoclasse di ReadOnlyCollection<T>, o in rari casi IEnumerable<T> per immobili o valori che rappresentano sola lettura collezioni ritorno.

Andiamo con ReadOnlyCollections per esprimere il nostro intento della raccolta restituita.

I metodi List<T> di cui si parla sono stati aggiunti in .NET 2.0 per comodità. In C# 3.0/.NET 3.5, è possibile recuperare tutti questi metodi su ReadOnlyCollection<T> (o qualsiasi IEnumerable<T>) utilizzando i metodi di estensione (e utilizzare anche gli operatori LINQ), quindi non penso ci sia alcuna motivazione per aggiungerli in modo nativo ad altri tipi . Il fatto che siano presenti su List è solo una nota storica a causa della presenza di metodi di estensione disponibili ora ma non in 2.0.

+2

Purtroppo la squadra è bloccata nella distorsione temporale del 2.0. –

3

Non ho idea del motivo per cui non sono stati aggiunti in origine. Ma ora che abbiamo LINQ, non vedo alcun motivo per aggiungerli nelle versioni future della lingua. I metodi che hai citato possono essere facilmente scritti in una query LINQ oggi. In questi giorni uso solo le query LINQ per praticamente tutto. In realtà mi infastidisco più spesso con List<T> con questi metodi perché è in conflitto con i metodi di estensione che scrivo nei confronti di IEnumerable<T>.

+0

Purtroppo la squadra è bloccata nella distorsione temporale del 2.0. –

+0

@ Mark, è consentito utilizzare VS2008 per compilare codice compatibile C# 2.0? Se è così, puoi semplicemente definire questi metodi di estensione da solo – JaredPar

+0

Nessun problema è che non hanno ancora licenze 2008. Apparentemente il piano per spostare il 2008 è stato sui libri per un po '. Nutss #! @ & * # –

7

Prima di tutto, ReadOnlyCollection<T> implementa IEnumerable<T> e IList<T>. Con tutti i metodi di estensione in .NET 3.5 e LINQ, si ha accesso a quasi tutte le funzionalità dalla classe originale List<T> in termini di query, che è tutto ciò che si dovrebbe fare con uno ReadOnlyCollection<T> comunque.

Detto questo, la tua domanda iniziale mi porta a dare qualche suggerimento ...

La restituzione di List<T> è una progettazione errata, quindi non dovrebbe essere un punto di confronto. List<T> deve essere utilizzato per l'implementazione, ma per l'interfaccia, è necessario restituire IList<T>. Lo stato Framework Design Guidelines particolare:

"NON uso ArrayList o List<T> nelle API pubbliche." (Pagina 251)

Se si tiene conto di ciò, non vi è assolutamente alcuno svantaggio per ReadOnlyCollection<T> rispetto a List<T>. Entrambe queste classi implementano IEnumerable<T> e IList<T>, che sono le interfacce che dovrebbero essere restituite comunque.

+0

Purtroppo la squadra è bloccata nella distorsione temporale del 2.0. –

+0

@ Mark Levison: anche in 2.0, si dovrebbe restituire IList , non List , quindi i commenti si applicano ancora. –

0

Penso che la risposta di Jeff kinda contenga la risposta che ti serve; invece di ReadOnlyCollection<T>, restituire una sottoclasse di esso ... uno che si implementa per includere i metodi che si desidera utilizzare senza eseguire l'aggiornamento a VS2008/LINQ.