문제

할 수 있는 누군가를 설명페이고 IEnumerator 요?

예를 들어,그것을 사용하는 경우 이상 foreach?의 차이점은 무엇페 및 IEnumerator?왜 우리는 그것을 사용할 필요가?

도움이 되었습니까?

해결책

예를 들어, Foreach를 사용할 때?

당신은 사용하지 않습니다 IEnumerable "위에" foreach. 구현 IEnumerable 사용합니다 foreach 가능한.

다음과 같은 코드를 작성할 때

foreach (Foo bar in baz)
{
   ...
}

작문과 기능적으로 동일합니다.

IEnumerator bat = baz.GetEnumerator();
while (bat.MoveNext())
{
   bar = (Foo)bat.Current
   ...
}

"기능적으로 동등한"이라는 의미는 실제로 컴파일러가 코드를 바꾸는 것임을 의미합니다. 당신은 사용할 수 없습니다 foreach ~에 baz 이 예에서 ~하지 않는 한 baz 구현 IEnumerable.

IEnumerable 그것을 의미합니다 baz 방법을 구현합니다

IEnumerator GetEnumerator()

그만큼 IEnumerator 이 메소드를 반환하는 객체는 메소드를 구현해야합니다

bool MoveNext()

그리고

Object Current()

첫 번째 방법은 다음 객체로 진행됩니다. IEnumerable 열거자를 생성 한 개체, 반환 false 완료되면 두 번째는 현재 객체를 반환합니다.

.NET에있는 모든 것은 과도한 구현을 반복 할 수 있습니다 IEnumerable. 자신의 수업을 구축하고 있고 아직 구현하는 수업에서 상속되지 않는 경우 IEnumerable, 당신은 당신의 수업을 사용할 수있게 할 수 있습니다 foreach 구현하여 진술 IEnumerable (그리고 새로운 GetEnumerator 메소드가 반환됩니다).

다른 팁

ienumerable 및 ienumerator 인터페이스

기존 .NET 인터페이스 구현 프로세스를 검토하기 위해 먼저 ienumerable 및 ienumerator의 역할을 살펴 보겠습니다. C#은 모든 배열 유형의 내용을 반복 할 수있는 foreach라는 키워드를 지원합니다.

// Iterate over an array of items.
int[] myArrayOfInts = {10, 20, 30, 40};
foreach(int i in myArrayOfInts)
{
   Console.WriteLine(i);
}

배열 유형만이 구성을 사용할 수있는 것처럼 보이지만,이 문제의 진실은 getEnumerator ()라는 방법을 지원하는 모든 유형입니다.

차고 수업이 있다고 가정합니다.

// Garage contains a set of Car objects.
public class Garage
{
   private Car[] carArray = new Car[4];
   // Fill with some Car objects upon startup.
   public Garage()
   {
      carArray[0] = new Car("Rusty", 30);
      carArray[1] = new Car("Clunker", 55);
      carArray[2] = new Car("Zippy", 30);
      carArray[3] = new Car("Fred", 30);
   }
}

이상적으로는 다양한 데이터 값과 마찬가지로 Foreach Construct를 사용하여 Garage Object의 하위 항목을 반복하는 것이 편리합니다.

// This seems reasonable ...
public class Program
{
   static void Main(string[] args)
   {
      Console.WriteLine("***** Fun with IEnumerable / IEnumerator *****\n");
      Garage carLot = new Garage();
      // Hand over each car in the collection?
      foreach (Car c in carLot)
      {
         Console.WriteLine("{0} is going {1} MPH",
         c.PetName, c.CurrentSpeed);
      }
      Console.ReadLine();
   }
}

안타깝게도 컴파일러는 차고 클래스가 getEnumerator ()라는 메소드를 구현하지 않음을 알려줍니다. 이 방법은 Ienumerable 인터페이스에 의해 공식화되며 System.collections 네임 스페이스 내에 숨어 있습니다. 이 동작을 지원하는 클래스 또는 구조는 그들이 서브 항목을 발신자에게 노출시킬 수 있음을 광고합니다 (이 예에서는 Foreach 키워드 자체). 이 표준 .NET 인터페이스의 정의는 다음과 같습니다.

// This interface informs the caller
// that the object's subitems can be enumerated.
public interface IEnumerable
{
   IEnumerator GetEnumerator();
}

보시다시피, getEnumerator () 메소드는 System.collections.ienumerator라는 다른 인터페이스에 대한 참조를 반환합니다. 이 인터페이스는 발신자가 ienumerable 호환 컨테이너가 포함하는 내부 객체를 통과 할 수 있도록 인프라를 제공합니다.

// This interface allows the caller to
// obtain a container's subitems.
public interface IEnumerator
{
   bool MoveNext (); // Advance the internal position of the cursor.
   object Current { get;} // Get the current item (read-only property).
   void Reset (); // Reset the cursor before the first member.
}

이러한 인터페이스를 지원하기 위해 차고 유형을 업데이트하려면 긴 도로를 취하고 각 방법을 수동으로 구현할 수 있습니다. getEnumerator (), movenext (), current 및 reset ()의 맞춤형 버전을 자유롭게 제공 할 수 있지만 더 간단한 방법이 있습니다. System.Array 유형 (및 기타 많은 컬렉션 클래스)은 이미 ienumerable 및 ienumerator를 구현하기 때문에 System.Array에 요청을 다음과 같이 단순히 위임 할 수 있습니다.

using System.Collections;
...
public class Garage : IEnumerable
{
   // System.Array already implements IEnumerator!
   private Car[] carArray = new Car[4];
   public Garage()
   {
      carArray[0] = new Car("FeeFee", 200);
      carArray[1] = new Car("Clunker", 90);
      carArray[2] = new Car("Zippy", 30);
      carArray[3] = new Car("Fred", 30);
   }
   public IEnumerator GetEnumerator()
   {
      // Return the array object's IEnumerator.
      return carArray.GetEnumerator();
   }
}

차고 유형을 업데이트 한 후에는 C# foreach 구조의 유형을 안전하게 사용할 수 있습니다. 또한 getEnumerator () 메소드가 공개적으로 정의 된 경우 객체 사용자는 ienumerator 유형과 상호 작용할 수도 있습니다.

// Manually work with IEnumerator.
IEnumerator i = carLot.GetEnumerator();
i.MoveNext();
Car myCar = (Car)i.Current;
Console.WriteLine("{0} is going {1} MPH", myCar.PetName, myCar.CurrentSpeed);

그러나 객체 수준에서 ienumerable의 기능을 숨기려는 경우 명시 적 인터페이스 구현을 사용하십시오.

IEnumerator IEnumerable.GetEnumerator()
{
  // Return the array object's IEnumerator.
  return carArray.GetEnumerator();
}

그렇게함으로써 캐주얼 객체 사용자는 차고의 getEnumerator () 메소드를 찾지 못하고, Foreach 구조는 필요할 때 백그라운드에서 인터페이스를 얻습니다.

Adapted from the Pro C# 5.0 및 .NET 4.5 프레임 워크

ienumerable 구현은 클래스가 ienumerator 객체를 반환한다는 의미입니다.

public class People : IEnumerable
{
    IEnumerator IEnumerable.GetEnumerator()
    {
        // return a PeopleEnumerator
    }
}

Ienumerator 구현은 클래스가 반복을위한 방법과 속성을 반환한다는 것을 의미합니다.

public class PeopleEnumerator : IEnumerator
{
    public void Reset()...

    public bool MoveNext()...

    public object Current...
}

어쨌든 그 차이입니다.

유추 + 코드 연습을 통한 설명

먼저 코드가없는 설명이 있으면 나중에 추가하겠습니다.

항공사 회사를 운영한다고 가정 해 봅시다. 그리고 각 비행기에서 당신은 비행기에서 비행기를 타는 승객에 대한 정보를 알고 싶습니다. 기본적으로 비행기를 "가로"할 수 있기를 원합니다. 다시 말해, 당신은 앞 좌석에서 시작한 다음 비행기 뒤쪽으로 길을 가고 승객들에게 정보를 물어보십시오. , 그렇다면 :

  1. 셀 수있는 것, 그리고
  2. 카운터가있는 경우.

왜 이러한 요구 사항이 있습니까? 그것이 인터페이스가 요구하는 것이기 때문입니다.

이것이 정보 과부하 인 경우, 당신이 알아야 할 것은 비행기의 각 승객에게 첫 번째부터 시작하여 마지막으로 시작하는 몇 가지 질문을 할 수 있기를 원한다는 것입니다.

Countable은 무엇을 의미합니까?

항공사가 "셀 수있는"경우 비행기에 승무원이 있어야한다는 것을 의미합니다.

  1. 카운터/승무원은 첫 번째 승객 전에 시작해야합니다 (데모 안전을 데모 안전하는 모든 사람 앞에서 구명 조끼를 켜는 방법 등).
  2. 그/그녀 (즉, 승무원)는 통로 위로 첫 자리로 "다음으로 이동"해야합니다.
  3. 그/그녀는 다음과 같이 기록해야합니다. (i) 사람이 자리에있는 사람과 (ii) 현재 위치.

계산 절차

항공사의 선장은 모든 승객이 조사 또는 계산시기에 대한 보고서를 원합니다. 따라서 첫 자리에있는 사람과 대화 한 후 비행 참석자/카운터는 선장에게보고하고 보고서가 제공되면 카운터는 통로에서 정확한 위치를 기억하고 떠난 곳을 계속 계산합니다. 끄다.

이런 식으로 선장은 항상 조사중인 현재 사람에 대한 정보를 가질 수 있습니다. 그렇게하면이 개인이 맨체스터 시티를 좋아한다는 사실을 알게되면 승객이 우선적으로 대우 할 수 있습니다.

  • 카운터는 비행기의 끝에 도달 할 때까지 계속됩니다.

이것을 ienumerables와 묶어 봅시다

  • 열거 가능한 것은 비행기에 승객 컬렉션 일뿐입니다. 민간 항공법 - 기본적으로 모든 ienumerables가 따라야하는 규칙입니다. 항공사 승무원이 Passeger 정보를 가지고 선장에게 갈 때마다, 우리는 기본적으로 승객을 선장에게 양보하고 있습니다. 선장은 기본적으로 승객과 함께 승객을 재배치하는 것을 제외하고는 승객과 원하는대로 할 수 있습니다. 이 경우 맨체스터 시티를 따르는 경우 우선적 인 치료를받습니다 (ugh!).

    foreach (Passenger passenger in Plane)
    // the airline hostess is now at the front of the plane
    // and slowly making her way towards the back
    // when she get to a particular passenger she gets some information
    // about the passenger and then immediately heads to the cabin
    // to let the captain decide what to do with it
    { // <---------- Note the curly bracket that is here.
        // we are now cockpit of the plane with the captain.
        // the captain wants to give the passenger free 
        // champaign if they support manchester city
        if (passenger.supports_mancestercity())
        {
            passenger.getFreeChampaign();
        } else
        {
            // you get nothing! GOOD DAY SIR!
        }
    } //  <---- Note the curly bracket that is here!
          the hostess has delivered the information 
          to the captain and goes to the next person
          on the plane (if she has not reached the 
          end of the plane)
    

요약

다시 말해, 무언가가 셀 수 있다면 셀 수 있습니다 카운터가 있습니다. 그리고 카운터는 (기본적으로)해야합니다 : (i) 그 장소를 기억합니다 (상태), (ii) 할 수 있습니다 다음으로 이동하십시오, (iii) 그리고에 대해 알고 있습니다 현재의 그가 다루고있는 사람.

열거 가능한 것은 "Countable"에 대한 멋진 단어 일뿐입니다. 다시 말해, 열거 가능한 것은 당신이 '열거'(즉, 카운트)를 허용합니다.

ienumerable GetEnumerator를 구현합니다. 호출되면 해당 방법이 반환됩니다 ienumerator Movenext, Reset 및 Current를 구현합니다.

따라서 클래스가 ienumerable을 구현하면 메소드 (getEnumerator)를 호출하고 새 개체를 반환 할 수 있다고 말합니다 (ienumerator).

구현페을 얻을 수 있습니 IEnumerator 리스트를 사용하세요.

IEnumerator 할 수 있습 foreach 스타일을 순차적으로 액세스하려면 항목 목록을 사용하여 수확량 키워드를 사용합니다.

전 foreach 구현(Java1.4,예를 들어),는 방법을 반복하 목록을 얻을 수 있었 열 목록에서 다음 요청을 위한"다음"항목 목록에 한 반환되는 값으로 다음 항목은 null 입니다.Foreach 단순히지 않는 암시적으로 언어의 기능,같은 방식으로 자물쇠()구현하 모니터 클래스고 있습니다.

제가 기대 foreach 에 작품을 나열하기 때문에 그들이 구현페.

  • 객체 구현 ienumerable 다른 사람들이 각 항목을 방문 할 수 있습니다 (열거 자에 의해).
  • 객체 구현 ienumerator 반복을 수행하는 것입니다. 열거 가능한 물체 위에 반복됩니다.

목록, 스택, 나무의 열거 가능한 물체를 생각하십시오.

ienumerable 및 ienumerator (및 그들의 일반적인 상대방은 ienumeribleu003CT> 그리고 ienumeratoru003CT> )는 기본 인터페이스입니다 반복자 구현 .NET Framework 클래스 Libray 컬렉션.

ienumerable 코드의 대부분에서 볼 수있는 가장 일반적인 인터페이스입니다. Foreach 루프, 발전기를 활성화합니다 (생각 생산하다) 그리고 작은 인터페이스 때문에, 그것은 단단한 추상화를 만드는 데 사용됩니다. ienumerable은 ienumerator에 따라 다릅니다.

ienumerator, 반면에, 약간 낮은 레벨 반복 인터페이스를 제공합니다. 그것은 명시 적 반복자 프로그래머가 반복주기를보다 잘 제어 할 수 있습니다.

ienumerable

ienumerable은 그것을 지원하는 컬렉션을 반복 할 수있는 표준 인터페이스입니다 (사실, 오늘날 내가 생각할 수있는 모든 수집 유형 ienumerable). 컴파일러 지원은 언어 기능과 같은 언어 기능을 허용합니다 foreach. 일반적으로이를 가능하게합니다 암시 적 반복자 구현.

foreach 루프

foreach (var value in list)
  Console.WriteLine(value);

제 생각에는 foreach 루프는 사용의 주요 이유 중 하나입니다 ienumerable 인터페이스. foreach 간결한 구문이 있으며 클래식에 비해 이해하기 쉽습니다. 다양한 변수를 확인하기 위해 다양한 변수를 확인 해야하는 루프 스타일.

수율 키워드

아마도 덜 알려진 기능은 아마도 그 것입니다 ienumerable 또한 활성화합니다 C#의 발전기 사용과 함께 yield return 그리고 yield break 진술.

IEnumerable<Thing> GetThings() {
   if (isNotReady) yield break;
   while (thereIsMore)
     yield return GetOneMoreThing();
}

추상화

실제로 또 다른 일반적인 시나리오는 사용하는 것입니다 ienumerable 최소한의 추상화를 제공합니다. 미세하고 읽기 전용 인터페이스이므로 컬렉션을 다음과 같이 노출하는 것이 좋습니다. ienumerable (대신 목록 예를 들어). 이렇게하면 고객의 코드를 위반하지 않고 구현을 자유롭게 변경할 수 있습니다 (목록 변경 목록을 Linkedlist 예를 들어).

Gotcha

알아야 할 한 가지 동작은 스트리밍 구현에서 (예 : 메모리에서 모든 결과를 먼저로드하는 대신 데이터베이스에서 행으로 데이터 행을 검색하는 것입니다) 할 수 없습니다 컬렉션을 두 번 이상 반복하십시오. 이는 마찬가지로 메모리 내 컬렉션과 대조적입니다 목록, 문제없이 여러 번 반복 할 수 있습니다. 예를 들어 Resharper, 코드 검사가 있습니다 ienumerable의 가능한 다중 열거.

ienumerator

반면에 ienumerator는 비하인드 스토리 인터페이스입니다. ienumerble-foreach-magic 일하다. 엄격하게 말하면 명시 적 반복자가 가능합니다.

var iter = list.GetEnumerator();
while (iter.MoveNext())
    Console.WriteLine(iter.Current);

내 경험에 ienumerator 더 많은 장황 구문과 약간 혼란스러운 의미론으로 인해 일반적인 시나리오에서는 거의 사용되지 않습니다. movenext () 이름이 전혀 제안하지 않는 값도 반환합니다.

ienumerator의 사용 사례

나는 만 사용했다 ienumerator 특히 (약간 낮은 수준) 라이브러리 및 제가 제공 한 프레임 워크 ienumerable 인터페이스. 한 가지 예는 일련의 객체를 foreach 반복적 인 비록 무대 뒤에서 데이터는 다양한 파일 스트림과 직렬화를 사용하여 수집되었습니다.

클라이언트 코드

foreach(var item in feed.GetItems())
    Console.WriteLine(item);

도서관

IEnumerable GetItems() {
    return new FeedIterator(_fileNames)
}

class FeedIterator: IEnumerable {
    IEnumerator GetEnumerator() {
        return new FeedExplicitIterator(_stream);
    }
}

class FeedExplicitIterator: IEnumerator {
    DataItem _current;

    bool MoveNext() {
        _current = ReadMoreFromStream();
        return _current != null;           
    }

    DataItem Current() {
        return _current;   
    }
}

구현 IEnumerable 본질적으로 객체를 반복 할 수 있음을 의미합니다. 이것은 반드시 색인화 할 수없는 특정 목록이 있지만 열거 할 수 있기 때문에 배열이라는 것을 의미하지는 않습니다.

IEnumerator 반복을 수행하는 데 사용되는 실제 객체입니다. 목록의 한 개체에서 다음 객체로 이동하는 것을 제어합니다.

대부분의 경우 IEnumerable & IEnumerator a의 일부로 투명하게 사용됩니다 foreach 고리.

ienumerable과 ienumerator의 차이점 :

  • ienumerable은 내부적으로 ienumerator를 사용합니다.
  • ienumerable은 어떤 항목/객체가 실행되는지 알 수 없습니다.
  • Ienumerator를 다른 기능으로 전달할 때마다 항목/객체의 현재 위치를 알고 있습니다.
  • ienumerable 컬렉션을 다른 기능으로 전달할 때마다 항목/객체의 현재 위치를 알지 못합니다 (어떤 항목이 실행중인 항목을 모릅니다)

    ienumerable 하나의 방법 getEnumerator ()가 있습니다.

public interface IEnumerable<out T> : IEnumerable
{
IEnumerator<T> GetEnumerator();
}

iEenumerator에는 하나의 속성 전류와 두 개의 메소드가 재설정 및 movenext (목록에서 항목의 현재 위치를 아는 데 유용함)를 가지고 있습니다.

public interface IEnumerator
{
     object Current { get; }
     bool MoveNext();
     void Reset();
}

반복자 패턴에 대한 이해가 도움이 될 것입니다. 나는 같은 것을 읽는 것이 좋습니다.

반복자 패턴

높은 수준에서 반복자 패턴을 사용하여 모든 유형의 컬렉션을 통해 반복하는 표준적인 방법을 제공 할 수 있습니다. 반복자 패턴, 실제 컬렉션 (클라이언트), 애그리 게이터 및 반복자에 3 명의 참가자가 있습니다. 집계는 반복기를 반환하는 메소드가있는 인터페이스/초록 클래스입니다. 반복자는 컬렉션을 통해 반복 할 수있는 방법이있는 인터페이스/초록 클래스입니다.

패턴을 구현하려면 먼저 해당 컬렉션 (클라이언트)을 반복 할 수있는 콘크리트를 생성하기 위해 반복자를 구현해야합니다. 컬렉션 (클라이언트)은 어 그리 게이터를 구현하여 위의 반복기의 인스턴스를 반환합니다.

UML 다이어그램은 다음과 같습니다Iterator Pattern

따라서 기본적으로 C#에서 ienumerable은 추상 집계이며 ienumerator는 추상 반복자입니다. ienumerable에는 원하는 유형의 ienumerator 인스턴스를 생성하는 단일 방법 GetEnumerator가 있습니다. 목록과 같은 컬렉션은 ienumerable을 구현합니다.

예시. 방법이 있다고 가정하자 getPermutations(inputString) 문자열의 모든 순열을 반환하고 메소드가 인스턴스를 반환합니다. IEnumerable<string>

순열의 수를 계산하기 위해 아래와 같은 일을 할 수 있습니다.

 int count = 0;
        var permutations = perm.getPermutations(inputString);
        foreach (string permutation in permutations)
        {
            count++;
        }

C# 컴파일러는 상기를 다소 변환합니다.

using (var permutationIterator = perm.getPermutations(input).GetEnumerator())
        {
            while (permutationIterator.MoveNext())
            {
                count++;
            }
        }

궁금한 점이 있으면 주저하지 마십시오.

ienumerable은 ienumerator를 포함하는 상자입니다. ienumerable은 모든 컬렉션의 기본 인터페이스입니다. 컬렉션이 ienumerable을 구현하면 foreach 루프가 작동 할 수 있습니다. 아래 코드에서는 우리 자신의 열거자를 갖는 단계를 설명합니다. 먼저 우리가 컬렉션을 만들 겠다는 수업을 정의하겠습니다.

public class Customer
{
    public String Name { get; set; }
    public String City { get; set; }
    public long Mobile { get; set; }
    public double Amount { get; set; }
}

이제 우리는 클래스 고객을위한 컬렉션 역할을하는 클래스를 정의 할 것입니다. 인터페이스를 구현하고 있습니다. 메소드 getEnumerator를 구현해야합니다. 이것은 우리의 사용자 정의 열거자를 반환합니다.

public class CustomerList : IEnumerable
{
    Customer[] customers = new Customer[4];
    public CustomerList()
    {
        customers[0] = new Customer { Name = "Bijay Thapa", City = "LA", Mobile = 9841639665, Amount = 89.45 };
        customers[1] = new Customer { Name = "Jack", City = "NYC", Mobile = 9175869002, Amount = 426.00 };
        customers[2] = new Customer { Name = "Anil min", City = "Kathmandu", Mobile = 9173694005, Amount = 5896.20 };
        customers[3] = new Customer { Name = "Jim sin", City = "Delhi", Mobile = 64214556002, Amount = 596.20 };
    }

    public int Count()
    {
        return customers.Count();
    }
    public Customer this[int index]
    {
        get
        {
            return customers[index];
        }
    }
    public IEnumerator GetEnumerator()
    {
        return customers.GetEnumerator(); // we can do this but we are going to make our own Enumerator
        return new CustomerEnumerator(this);
    }
}

이제 우리는 다음과 같이 자신의 사용자 정의 열거자를 만들 것입니다. 따라서 MOVENEXT 메소드를 구현해야합니다.

 public class CustomerEnumerator : IEnumerator
    {
        CustomerList coll;
        Customer CurrentCustomer;
        int currentIndex;
        public CustomerEnumerator(CustomerList customerList)
        {
            coll = customerList;
            currentIndex = -1;
        }

        public object Current => CurrentCustomer;

        public bool MoveNext()
        {
            if ((currentIndex++) >= coll.Count() - 1)
                return false;
            else
                CurrentCustomer = coll[currentIndex];
            return true;
        }

        public void Reset()
        {
            // we dont have to implement this method.
        }
    }

이제 아래와 같이 컬렉션을 통해 Foreach Loop을 사용할 수 있습니다.

    class EnumeratorExample
    {
        static void Main(String[] args)
        {

            CustomerList custList = new CustomerList();
            foreach (Customer cust in custList)
            {
                Console.WriteLine("Customer Name:"+cust.Name + " City Name:" + cust.City + " Mobile Number:" + cust.Amount);
            }
            Console.Read();

        }
    }

사소한 기여.

그들 중 많은 사람들이 '사용하는시기'와 'Foreach와 함께 사용'에 대해 설명합니다. 나는 다른 것을 추가 할 생각을했다 상태 차이 여기서는 Ienumerable a ienumerator의 차이에 대해 의문의 여지가 있습니다.

아래 토론 스레드를 기반으로 아래 코드 샘플을 만들었습니다.

ienumerable, ienumerator vs foreach, 언제 무엇을 사용 해야하는지 ienumerator와 ienumerable의 차이점은 무엇입니까?

열거자는 기능 호출 사이의 상태 (반복 위치)를 보존하는 반면 반복은 다른 손에 열거 할 수있는 반복은 그렇지 않습니다.

다음은 이해할 주석이있는 테스트 된 예입니다.

전문가를 추가/수정하십시오.

static void EnumerableVsEnumeratorStateTest()
{
    IList<int> numList = new List<int>();

    numList.Add(1);
    numList.Add(2);
    numList.Add(3);
    numList.Add(4);
    numList.Add(5);
    numList.Add(6);

    Console.WriteLine("Using Enumerator - Remembers the state");
    IterateFrom1to3(numList.GetEnumerator());

    Console.WriteLine("Using Enumerable - Does not Remembers the state");
    IterateFrom1to3Eb(numList);

    Console.WriteLine("Using Enumerable - 2nd functions start from the item 1 in the collection");
}

static void IterateFrom1to3(IEnumerator<int> numColl)
{
    while (numColl.MoveNext())
    {
        Console.WriteLine(numColl.Current.ToString());

        if (numColl.Current > 3)
        {
            // This method called 3 times for 3 items (4,5,6) in the collection. 
            // It remembers the state and displays the continued values.
            IterateFrom3to6(numColl);
        }
    }
}

static void IterateFrom3to6(IEnumerator<int> numColl)
{
    while (numColl.MoveNext())
    {
        Console.WriteLine(numColl.Current.ToString());
    }
}

static void IterateFrom1to3Eb(IEnumerable<int> numColl)
{
    foreach (int num in numColl)
    {
        Console.WriteLine(num.ToString());

        if (num>= 5)
        {
            // The below method invokes for the last 2 items.
            //Since it doesnot persists the state it will displays entire collection 2 times.
            IterateFrom3to6Eb(numColl);
        }
    }
}

static void IterateFrom3to6Eb(IEnumerable<int> numColl)
{
    Console.WriteLine();
    foreach (int num in numColl)
    {
        Console.WriteLine(num.ToString());
    }
}

이러한 차이점을 발견했습니다.

A. 우리는 목록을 다른 방식으로 반복합니다. foreach는 ienumerable 및 ienumerator에 루프에 사용할 수 있습니다.

B. ienumerator는 한 메서드에서 다른 방법으로 전달할 때 (현재 색인으로 작동)를 기억할 수 있지만 Ienumerable은 인덱스를 기억할 수 없으며 인덱스를 시작으로 재설정 할 수 없습니다. 이 비디오에서 더 https://www.youtube.com/watch?v=jd3yujgc9m0

IEnumerable 그리고 IEnumerator 둘 다 C#의 인터페이스입니다.

IEnumerable 단일 메소드를 정의하는 인터페이스입니다 GetEnumerator() 그것은 반환합니다 IEnumerator 상호 작용.

이를 통해 컬렉션에 대한 읽기 전용 액세스 IEnumerable A와 함께 사용할 수 있습니다 foreach 성명.

IEnumerator 두 가지 방법이 있습니다. MoveNext 그리고 Reset. 또한 부동산이 있습니다 Current.

다음은 ienumerable 및 ienumerator의 구현을 보여줍니다.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Enudemo
{

    class Person
    {
        string name = "";
        int roll;

        public Person(string name, int roll)
        {
            this.name = name;
            this.roll = roll;
        }

        public override string ToString()
        {
            return string.Format("Name : " + name + "\t Roll : " + roll);
        }

    }


    class Demo : IEnumerable
    {
        ArrayList list1 = new ArrayList();

        public Demo()
        {
            list1.Add(new Person("Shahriar", 332));
            list1.Add(new Person("Sujon", 333));
            list1.Add(new Person("Sumona", 334));
            list1.Add(new Person("Shakil", 335));
            list1.Add(new Person("Shruti", 336));
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
           return list1.GetEnumerator();
        }
    }



    class Program
    {
        static void Main(string[] args)
        {
            Demo d = new Demo();  // Notice here. it is simple object but for 
                                //IEnumerator you can get the collection data

            foreach (Person X in d)
            {
                Console.WriteLine(X);
            }

            Console.ReadKey();
        }
    }
}
/*
Output : 

Name : Shahriar  Roll : 332
Name : Sujon     Roll : 333
Name : Sumona    Roll : 334
Name : Shakil    Roll : 335
Name : Shruti    Roll : 336
  */
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top