O que é um sólido pedaço reutilizável, elegante, de código para determinar se um IEnumerable está vazio, em .NET?

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

  •  02-07-2019
  •  | 
  •  

Pergunta

Eu estou tentando encontrar o mais reutilizável, mas elegante, pedaço de código possível para determinar se um IEnumerable. No ideal, esta deve ser uma função que eu posso chamar de absolutamente qualquer momento eu preciso de dizer se um IEnumerable está vazio.

Embora eu tenha desenvolvido uma resposta para .NET 3.5 que tem funcionado bem para mim até agora, o meu pensamento atual é que não existe uma resposta perfeita, uma vez que um IEnumerable pode tecnicamente encapsular uma coleção (ou fila de iteradores) que modifica o Os resultados básicos como ele repete, o que causaria problemas. No entanto, isso também seria um impedimento para a implementação IEnumerable.Count (), e que não parou MS de fornecê-lo.

Então, eu pensei que eu iria colocá-lo para SO para ver se alguém tem um melhor, e no caso de alguém deve achar que é útil.

Editar: Uau, eu não posso acreditar que eu não sabia sobre IEnumerable.Any. Eu sabia que existia, mas nunca se preocupou em verificar o que ele fez. Que isso sirva de lição. Leia a documentação. Só porque um nome de método não implica que ele faz o que você quer, não significa que ele não faz o que você quer.

Foi útil?

Solução

!enumerable.Any()

Tentará pegar apenas o primeiro elemento.

Para expandir sobre como / por que isso funciona, qualquer determina se qualquer um dos componentes de um IEnumerable coincidir com uma determinada função, se nenhum for dado, então qualquer componente irá ter sucesso, ou seja, a função retornará verdadeiro se um elemento existe no enumeráveis.

Outras dicas

Para .net 1/2:

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

Ou, com os genéricos:

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

Você está certo de que não existe uma resposta perfeita. IEnumerable suporta apenas iteração e não garante que a enumeração é repetível. Você não pode descobrir se uma enumeração contém elementos sem chamar MoveNext pelo menos uma vez, e uma vez que você fez para que você não pode garantir que ser capaz de reutilizar a enumeração: é permitido para IEnumerable.Reset para lançar um NotSupportedException. De http://msdn.microsoft.com/en -us / library / system.collections.ienumerator.reset.aspx :

"O Reset método é fornecido para COM interoperabilidade Isso não significa necessariamente precisam ser implementadas;.. Em vez disso, o implementador pode simplesmente lançar um NotSupportedException"

Os métodos de extensão como IEnumerable .Count e IEnumerable necessidade .any chamar MoveNext debaixo das cobertas. wrappers úteis, mas não evitar o fato de que, nos casos (raros) onde uma enumeração não suporta Reset, você poderia ter um problema.

Uma coisa que ter cuidado com qualquer um destes métodos é que nem todas as contagens podem ser revertidas, por exemplo todas as implementações de System.Data.IDataReader só pode ser executado através de uma vez.

Nestes casos, você realmente não têm um custo em um loop foreach, desde que você conta para o fato de que ele pode até não loop de uma vez.

O primeiro método tem uma implementação simples de método de extensão vazio: http://signum.codeplex.com/SourceControl/changeset/view/25903# 510468

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top