Enumerazione ordinata: IEnumerable o Array (in C #)?

8

Contesto tipico: creo un metodo di estensione per una raccolta che considera che gli elementi siano ordinati. La funzione inizia all'inizio, all'indice 0 e l'ordine ha significato. Esempi: Raggruppamento per sequenza o Indici di un elemento .

Tuttavia, sono sempre perplesso su cosa estendere: IEnumerable<T> o T[] . Il mio fondamento logico era la chiarezza di scopo: un array ha una nozione di ordinamento, mentre un IEnumerable è implementato da molte collezioni generiche, non tutte hanno una nozione di ordine:

  • Dizionario - non ordinato
  • HashSet - non ordinato
  • LinkedList - ordinato
  • Elenco - ordinato
  • Coda - ordinata
  • SortedDictionary - ordinato (non nell'ordine originale)
  • SortedList - ordinato (non originale)
  • SortedSet - ordinato (non originale)
  • Stack - invertito

Così come ogni altra implementazione che potrebbe o non potrebbe essere ordinata.

Inoltre, non sono sicuro che l'enumeratore venga resettato se non viene completata un'enumerazione, quindi se è una preoccupazione, allora chissà a che punto inizierà l'enumerazione? L'enumerazione di un array inizia sempre all'inizio.

Quindi per me ha più senso estendere un T[] . Ma ho ragione a pensarlo? Mi sto preoccupando troppo? Qual è l'approccio corretto per garantire l'enumerazione "ordinata"?

    
posta MPelletier 09.12.2011 - 02:31
fonte

3 risposte

13

I'm not certain if the enumerator is reset if an enumeration is not completed, so if that's a worry, then who knows at what point the enumeration would start? Enumerating an array would always start at the beginning.

Queste due frasi mi fanno pensare che tu abbia profondi equivoci su come funziona il modello enumerabile. Puoi spiegare perché pensi che un enumeratore abbandonato abbia qualcosa a che fare con una successiva enumerazione ?

Un enumerabile è un dispositivo che produce enumeratori . Se un enumeratore viene abbandonato, ciò non influisce in alcun modo sull'enumerabile. Se vendo libri e Bob compra un libro e lo legge solo a metà strada, ciò non significa che quando vendo una copia diversa del libro ad Alice, deve iniziare a leggere dove Bob ha lasciato.

I'm always stumped as to what to extend: IEnumerable<T> or T[]. My rationale was clarity of purpose: An array has a notion of ordering, whereas an IEnumerable is implemented by many generic collections, not all of which have a notion of order:

Il tuo metodo di estensione deve (1) accedere alla raccolta senza ordine? (2) scrivi alla collezione?

Se è così, estendi IList<T> In caso contrario, estendi IEnumerable<T> .

Che dire: (3) passare la raccolta a un metodo che si aspetta un array?

Quindi estendi la matrice.

La tua domanda è fondamentalmente "Non so se estendere l'animale o la giraffa". Se il tuo metodo di estensione non è specifico per le giraffe, estendi Animal. Se il tuo metodo di estensione non è specifico per gli array, estendi tutti gli elenchi. Se non è specifico per gli elenchi, estendi tutte le sequenze. Se non è specifico per le sequenze, le probabilità sono buone che un metodo di estensione sia il meccanismo sbagliato per te; Mi raccomando contro l'estensione di tutti gli oggetti.

    
risposta data 09.12.2011 - 08:19
fonte
2

Penso che tu voglia combinare 2 concetti diversi in 1. La struttura dei dati e il suo ordine dei contenuti sono 2 cose separate.

L'ordine è un argomento delicato. Ad esempio, cosa significa ordinare un elenco di persone? Anche quando la chiave ordine / ordinamento è definita, deve avere una direzione e devi decidere cosa fare con null (se presente), problemi con la data, ecc.

Se l'ordine dei dati è importante per il tuo metodo, allora il tuo metodo potrebbe essere responsabile per l'ordine dei dati come parte della sua configurazione invece di chiedere i dati che devono essere ordinati dal chiamante. Un approccio simile viene utilizzato da alcuni algoritmi di corrispondenza delle stringhe in cui un dizionario viene creato all'interno del metodo di ricerca dalla stringa passata prima che la stringa venga cercata. So che questo non è il caso esatto, ma è l'esempio più vicino a cui potrei pensare.

    
risposta data 09.12.2011 - 03:44
fonte
1

IEnumerable dichiara che la raccolta che hai può essere enumerata; non implica nulla sul contenuto. Questa non è una brutta cosa: i contenitori possono avere capacità e restrizioni aggiuntive in cima alle singole interfacce.

(Non vedo come sia meglio un array qui - è indicizzabile, come un IList e altri contenitori, ma non c'è nulla sull'indicizzazione che implica l'ordine dei dati. La tua lista è abbastanza strana: alcuni elementi sono "ordinati" in quanto preservano l'ordine di inserzione, altri sono "ordinati" come sono ordinati, sono due cose diverse. A parte il SortedSet / SortedList / SortedDictionary, non dovresti assumere che i dati siano in un ordine particolare a meno che lo gestisci all'interno del tuo codice.)

Tuttavia, IEnumerable fornisce un'estensione LINQ che consente di .OrderBy, quindi tutto ciò che è enumerable può essere restituito in un ordine ordinato IOrderedEnumerable. Questa è un'interfaccia specifica per LINQ (e non implementata di default da SortedSet / SortedList / SortedDictionary, quindi potrebbe non avere senso estendere quella particolare interfaccia ...)

    
risposta data 09.12.2011 - 02:50
fonte

Leggi altre domande sui tag