Interfacce di raccolta in C #, provenienti da Java

4

In Java, sono abituato a dichiarare le collezioni utilizzando l'interfaccia più astratta possibile e quindi a costruirle utilizzando l'implementazione concreta che ha senso al momento. Di solito è simile a questo:

public class MyStuff {
    private Map<String, Address> customerAddresses;
    private List<ToDoItem> tasks;
    private Set<Person> people;

    public MyStuff() {
        customerAddresses = new HashMap<String, Address>();
        tasks = new ArrayList<ToDoItem>();
        people = new HashSet<Person>();
    }
}

Questo mi consente una maggiore flessibilità nel modificare l'implementazione di una raccolta in un secondo momento, quando tutto ciò che realmente dipendo è l'interfaccia di alto livello (cioè ho bisogno di qualcosa per memorizzare coppie chiave-valore, o qualcosa per memorizzare i dati ordinati) ed è generalmente considerata una "best practice" standard in Java.

Sto solo iniziando a programmare in C #, però, e non sono sicuro se esiste una pratica equivalente per la gerarchia delle collezioni di C #. Le raccolte in C # differiscono dalle raccolte in Java in diversi modi: Collection è un tipo concreto, l'interfaccia ICollection espone metodi simili a Set di Java mentre l'interfaccia ISet specifica molte più funzionalità e il set di chiavi o il set di valori di Dictionary non è un ISet , per nominarne alcuni. Ha senso fare qualcosa di simile in C #?

public class MyStuff {
    private IDictionary<String, Address> customerAddresses;
    private IList<ToDoItem> tasks;
    private ISet<Person> people;

    public MyStuff() {
        customerAddresses = new Dictionary<String, Address>();
        tasks = new List<ToDoItem>();
        people = new HashSet<Person>();
    }
}

O ci sono diverse interfacce e implementazioni "standard" da utilizzare per tali raccolte? Dovrei utilizzare ICollection e Collection al posto di Set o List ? Sono tentato di utilizzare le classi e le interfacce C # che "sembrano più vicine" a quelle Java a cui sono abituato, ma preferirei utilizzare l'impostazione che si adatta meglio ai paradigmi e agli standard C #.

    
posta Edward 01.08.2013 - 02:20
fonte

2 risposte

8

IEnumerable<T> è l'interfaccia da utilizzare. È l'interfaccia di base disponibile per gli oggetti del tipo di raccolta. IEnumerable<T> può essere utilizzato in foreach loop. Contiene anche numerosi metodi di estensione molto utili, che ti consentono di fare qualsiasi cosa, convertendolo in un elenco chiamando ToList() , filtrando i risultati chiamando Where(x => { //filtering functionality } e tutti i tipi di altre cose.

L'altra interfaccia da utilizzare è IDictionary<U, V> , che è l'interfaccia da utilizzare per i dizionari. ConcurrentDictionary<TKey, TValue> è probabilmente il più utile dei tipi di dizionari concreti standard poiché è progettato (abbastanza stranamente) per la concorrenza.

Qualunque cosa tu faccia, evita di usare List<T> al di fuori delle variabili locali.

L'altra cosa da notare è che LinkedList<T> non implementa l'interfaccia IList<T> .

    
risposta data 01.08.2013 - 05:53
fonte
3

La differenza tra ICollection e Set è che ICollection rappresenta una raccolta arbitraria di elementi, mentre Set e ISet rappresentano insiemi matematici, ad es. nessun articolo o elemento duplicato non ha un ordine definito. La versione di .NET ha più metodi, perché queste operazioni sono previste da insiemi matematici. Il motivo per cui IDictionary non implementa ISet è molto probabilmente perché allora KeyValuePair<Key,Value> deve aver definito l'uguaglianza corretta, che avrebbe richiesto transitivamente Value per avere un'uguaglianza definita. Ma IDictionary richiede che sia definita l'uguaglianza per Key e non Value .

Inoltre dovresti conoscere la Differenza tra List (T) e Collection (T) in .NET

    
risposta data 01.08.2013 - 08:52
fonte

Leggi altre domande sui tag