Pergunta

Uma questão entrevista para um emprego .NET 3.5 é "Qual é a diferença entre um iterador e um enumerador"?

Esta é uma distinção núcleo de fazer, o que com LINQ, etc.

De qualquer forma, qual é a diferença? Eu não consigo encontrar uma definição sólida na rede. Não se engane, eu posso encontrar o significado dos dois termos, mas eu recebo respostas ligeiramente diferentes. Qual seria a melhor resposta para uma entrevista?

OMI um iterador "repete" sobre uma coleção, e um enumerador fornece a funcionalidade para iterate, mas isso tem de ser chamado.

Além disso, usando a palavra-chave yield é dito para salvar o estado. O que é exatamente este estado? Há um exemplo deste benefício ocorrendo?

Foi útil?

Solução

meios iteração repetir alguns passos, ao enumerar significa passar por todos os valores em uma coleção de valores. Então, enumerando geralmente requer algum tipo de iteração.

Desta forma, enumerando é um caso especial de iteração onde o passo é obter um valor de uma coleção.

Observe o "normalmente" -. Enumerando também pode ser realizada de forma recursiva, mas recursão e iteração são tão intimamente relacionados que eu não se preocupam com esta pequena diferença

Você também pode valores Enumerar você não armazenar explicitamente em uma coleção. Por exemplo, você pode enumerar o número natural, primos, ou o que quer, mas você calcular esses valores durante a enumeração e não recuperá-los a partir de um acervo físico. Você entende neste caso, como enumerando uma coleção virtual com seus valores definidos por alguma lógica.


Eu assumo Reed Copsey pegou o ponto. Em C #, existem duas maneiras principais para enumerar algo.

  1. Implementar Enumerable e uma classe que implementa IEnumerator
  2. Implementar um iterador com a declaração yield

A primeira forma é mais difícil de implementar e usa objetos para enumerar. A segunda maneira é mais fácil de implementar e usos continuações.

Outras dicas

Em C # 2+, iterators é um caminho para o compilador para gerar automaticamente o IEnumerable e / ou IEnumerable interfaces de para você.

Sem iteradores, você precisa criar uma classe que implementa IEnumerator , incluindo a corrente, MoveNext e reset. Isto requer uma quantidade justa de trabalho. Normalmente, você poderia criar uma classe privada que implemtented IEnumerator para o seu tipo, então yourClass.GetEnumerator () iria construir essa classe privada, e devolvê-lo.

Iterators são um caminho para o compilador para gerar automaticamente isso para você, usando uma sintaxe simples (de rendimento). Isto permite-lhe implementar GetEnumerator () diretamente em sua classe, sem uma segunda classe (A IEnumerator) sendo especificado por você. A construção dessa classe, com todos os seus membros, é feito para você.

Iterators são muito desenvolvedor amigável - as coisas são feitas de uma forma muito eficiente, com muito menos esforço

.

Quando você usa foreach, os dois irão se comportar de forma idêntica (desde que você escrever corretamente o seu personalizado IEnumerator). Iterators apenas tornar a vida muito mais simples.

O C # chama de iterador é mais comumente (fora do mundo do C #) chamado de gerador ou gerador (por exemplo, em Python). A função do gerador é um caso especializado de coroutine . A C # iterador (gerador) é uma forma especial de um recenseador (um tipo de dados que implementa a interface IEnumerable).

Não gosto deste uso do iterador prazo para um gerador de C #, porque é tanto um enumerador, pois é um iterador. Muito tarde para Microsoft para mudar sua mente embora.

Por contraste considerar que em C ++ uma iteração é um valor que é utilizado principalmente para o acesso elementos sequenciais em uma colecção. Pode ser avançado, derferenced para recuperar um valor, e testado para ver se o final da coleção foi atingido.

Para entender iterators primeiro precisamos entender recenseadores.

Os recenseadores são objetos especializadas que fornecem um com os meios para percorrer uma lista ordenada de itens um de cada vez (o mesmo tipo de coisa é às vezes chamado de ‘cursor’). O .NET framework fornece duas interfaces importantes relacionadas com os entrevistadores: IEnumerator e IEnumerable. Objetos que implementam IEnumerator são eles próprios entrevistadores; que suportam os seguintes membros:

  • a propriedade atual, que aponta para uma posição na lista

  • o método MoveNext, que move a um item atual ao longo da lista

  • o método Reset, que move o item actual para a sua posição inicial (que está diante do primeiro item).

Por outro lado, Iter?tors implementar o p?ttern enumer?tor. NET 2.0 apresenta o iter?tor, que é ? enumer?tor m?nifested-compilador. Quando o objeto enumer?ble c?lls GetEnumer?tor, direta ou indiretamente, os gener?tes compilador ?nd retornos ?n objeto iter?tor ?ppropri?te. Option?lly, o iter?tor c?n ser combinado ? enumer?ble objecto ?nd enumer?tor.

O ingrediente essenti?l de bloco iter?tor ?n é o st?tement rendimento. Há uma grande diferença entre iter?tors ?nd enumer?tors: Iter?tors não implementar o método Reset. C?lling o método Reset no ?n iter?tor c?uses ?n exceção.

O ponto de iteradores é permitir a fácil implementação dos recenseadores. Quando um método precisa retornar tanto um enumerador ou uma classe enumeráveis ??para uma lista ordenada de itens, está escrito, de modo a voltar cada item em sua ordem correta usando a instrução ‘rendimento’.

"Considerando uma declaração foreach é o consumidor do recenseador, um iterador é o produtor do recenseador."

A descrição acima é como "C # 5.0 in a Nutshell", explica ele, e tem sido útil para mim.

Em outras palavras, a declaração foreach usa MoveNext () e a propriedade atual do IEnumerator para percorrer uma seqüência, enquanto o iterador é usado para produzir a implementação do IEnumerator que será usado pela instrução foreach. Em C #, quando você escreve um método iterator contendo uma declaração de rendimento, o compilador irá gerar um recenseador privado para você. E quando você percorrer os itens na seqüência, ele irá chamar o MoveNext () e propriedade atual do enumerador privado. Estes métodos / propriedades são implementadas por seu código no método iterator que será chamado repeately para produzir valores até que não existem valores deixados para produzir.

Este é o meu entendimento de como C # define recenseadores, e iteradores.

Uma vez que não foram dados exemplos, aqui está um que foi útil para mim.

Um enumerador é um objeto que você começa quando você chamar .GetEnumerator () em uma classe ou tipo que implementa a interface IEnumerator. Quando esta interface é implementada, você criou todo o código necessário para a compilor para que você possa usar foreach para "iterate" sobre sua coleção.

não recebem essa palavra 'iterate" confundido com iterator embora. Tanto o Enumerator e o iterador permitir que você 'iterate'. Enumerando e iteração são basicamente o mesmo processo, mas são implementadas de forma diferente. Enumerando significa que você impleneted a interface IEnumerator. Iterating significa que você criou a construção iterador em sua classe (demonstrado abaixo), e você está chamando foreach em sua classe, momento em que o compilor cria automaticamente a funcionalidade recenseador para você.

Além disso, note que você não tem que fazer agachamento com o seu entrevistador. Você pode chamar MyClass.GetEnumerator() durante todo o dia, e não fazer nada com ele (exemplo:

IEnumerator myEnumeratorThatIWillDoNothingWith = MyClass.GetEnumerator()).

Note também que o seu iterador construção em sua classe só realmente se acostuma quando você está realmente usando-o, ou seja, que você chamou foreach em sua classe.

Aqui está um exemplo iterador de MSDN :

public class DaysOfTheWeek : System.Collections.IEnumerable
{

     string[] days = { "Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat" };

     //This is the iterator!!!
     public System.Collections.IEnumerator GetEnumerator()
     {
         for (int i = 0; i < days.Length; i++)
         {
             yield return days[i];
         }
     }

}

class TestDaysOfTheWeek
{
    static void Main()
    {
        // Create an instance of the collection class
        DaysOfTheWeek week = new DaysOfTheWeek();

        // Iterate with foreach - this is using the iterator!!! When the compiler
        //detects your iterator, it will automatically generate the Current, 
        //MoveNext and Dispose methods of the IEnumerator or IEnumerator<T> interface
        foreach (string day in week)
        {
            System.Console.Write(day + " ");
        }
    }
}
// Output: Sun Mon Tue Wed Thr Fri Sat

"Iterators são um novo recurso do C # 2.0. Um iterador é um método, get acessador ou operador que permite apoiar iteração foreach em uma classe ou estrutura sem ter de implementar toda a interface IEnumerable. Em vez disso, você fornece apenas uma iterator, que simplesmente atravessa as estruturas de dados em sua classe. Quando o compilador detecta o iterador, ele irá gerar automaticamente os métodos atuais, MoveNext e elimine a interface IEnumerable ou IEnumerable." - MSDN

enumeração lida com objetos enquanto iteração lida com apenas valores. Enumeração é usada quando usamos vector hashtable etc enquanto iteração são utilizados em while loop etc. Eu nunca utilizar a palavra-chave yield então eu não poderia dizer-lhe.

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