Che cos'è un codice solido, elegante, riutilizzabile per determinare se un IEnumerable è vuoto, in .NET?

StackOverflow https://stackoverflow.com/questions/117355

  •  02-07-2019
  •  | 
  •  

Domanda

Sto cercando di trovare il codice più riutilizzabile, ma elegante, possibile per determinare se un IEnumerable. Nell'ideale, questa dovrebbe essere una funzione che posso chiamare assolutamente ogni volta che devo dire se un IEnumerable è vuoto.

Mentre ho sviluppato una risposta per .NET 3.5 che finora ha funzionato bene per me, il mio pensiero attuale è che non esiste una risposta perfetta, dal momento che un IEnumerable può tecnicamente incapsulare una raccolta (o una coda di iteratori) che modifica il risultati sottostanti mentre ripetono, il che causerebbe problemi. Tuttavia, ciò costituirebbe anche un ostacolo all'implementazione di IEnumerable.Count () e ciò non ha impedito a MS di fornirlo.

Quindi ho pensato di metterlo a SO per vedere se qualcuno ne ha uno migliore, e nel caso qualcun altro lo trovasse utile.

Modifica: Wow, non posso credere di non sapere di IEnumerable. Sapevo che esisteva, ma non mi sono mai preso la briga di controllare cosa facesse. Lascia che questa sia una lezione. Leggi la documentazione Solo perché il nome di un metodo non implica che fa quello che vuoi, non significa che non fa quello che vuoi.

È stato utile?

Soluzione

!enumerable.Any()

Tenterà di afferrare solo il primo elemento.

Per espandere il modo in cui funziona, qualsiasi determina se uno qualsiasi dei componenti di una IEnumerable corrisponde a una determinata funzione, se non ne viene fornito nessuno, allora qualsiasi componente avrà successo, il che significa che la funzione tornerà vera se esiste un elemento nell'enumerabile.

Altri suggerimenti

Per .net 1/2:

IEnumerator e;
try
{
   e = enumerable.GetEnumerator();
   return e.MoveNext();
}
finally
{ 
    if (e is IDisposable)
        e.Dispose();
}

Oppure, con generici:

using (IEnumerator<T> e = enumerable.GetEnumerator())
{
    return e.MoveNext();
}

Hai ragione sul fatto che non esiste una risposta perfetta. IEnumerable supporta solo l'iterazione e non garantisce che l'enumerazione sia ripetibile. Non è possibile scoprire se un'enumerazione contiene elementi senza chiamare MoveNext almeno una volta e, una volta fatto, non è possibile garantire di poter riutilizzare l'enumerazione: è consentito a IEnumerable.Reset generare NotSupportedException. Da http://msdn.microsoft.com/en -us / library / system.collections.ienumerator.reset.aspx :

" Il metodo di ripristino è fornito per l'interoperabilità COM. Non deve necessariamente essere implementato; invece, l'implementatore può semplicemente lanciare NotSupportedException. "

Metodi di estensione come IEnumerable < T > .Count e IEnumerable < T > .Qualcuno deve chiamare MoveNext sotto le copertine. Wrapper utili, ma non evitare il fatto che nei (rari) casi in cui un'enumerazione non supporta Reset, potresti avere un problema.

Una cosa a cui prestare attenzione con uno di questi metodi è che non è possibile eseguire il rollback di tutte le enumerazioni, ad esempio tutte le implementazioni di System.Data.IDataReader possono essere eseguite una sola volta.

In questi casi in realtà non hai un costo in un ciclo foreach, purché tieni conto del fatto che potrebbe non essere nemmeno ripetuto una volta.

Il primo metodo ha una semplice implementazione del metodo di estensione vuoto: http://signum.codeplex.com/SourceControl/changeset/view/25903# 510468

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top