Pergunta

Eu estava curioso para ver como o método SingleOrFallback foi implementado em MoreLINQ e descobriu algo Eu não tinha visto antes:

    public static T SingleOrFallback<T>(this IEnumerable<T> source, Func<T> fallback)
    {
        source.ThrowIfNull("source");
        fallback.ThrowIfNull("fallback");
        using (IEnumerator<T> iterator = source.GetEnumerator())
        {
            if (!iterator.MoveNext())
            {
                return fallback();
            }
            T first = iterator.Current;
            if (iterator.MoveNext())
            {
                throw new InvalidOperationException();
            }
            return first;
        }
    }

Por que o IEnumerator<T> em um comunicado using? Isto é algo que deve ser pensado quando se utiliza o foreach em um IEnumerable<T> também?

questão Side: O que este método faz exatamente? Será que devolver o item fallback sempre que a seqüência de origem não contém exatamente um produto?

Foi útil?

Solução

IEnumerator<T> estende IDisposable, então você deve tê-lo em uma instrução using. foreach faz isso automaticamente. (O IEnumerator não-genérico não estender IDisposable mas o compilador C # ainda gera código para Dispose chamada condicionalmente. Este foi um dos (poucos) variar entre C # 1.0 e 1.2, onde 1.2 é a versão transporte com .NET 1.1, por algum motivo).

Aqui está um artigo explicar por que isso é importante no contexto do iterador blocos.

Quanto ao que o método faz:

  • Se a sequência estiver vazia, retornar o item fallback
  • Se a sequência tem exatamente um item, devolvê-lo
  • Se a sequência tem mais de um item, lançar uma exceção

PS: É bom ver MoreLINQ está recebendo alguma atenção:)

Outras dicas

Alguns recenseadores irão se comportar mal se Descarte não é chamado; isso é tão verdadeiro para os não-genéricos como os genéricos (os não-genéricos requerem que o código seja pato-digite a chamada Descarte ou então elenco para IDisposable e depois chamar IDisposable.Dispose). É bom como uma questão de hábito para garantir que os objetos IEnumerator obter eliminados; Eu considero que é necessário para correção de qualquer rotina que aceita um IEnumerable de tipo desconhecido.

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