foreach 문에서 Visual C# 클래스를 사용할 수 있도록 만들기
이 문서에서는 및 IEnumerator
인터페이스를 사용하여 IEnumerable
문에서 foreach
사용할 수 있는 클래스를 만드는 방법을 보여 줍니다.
원래 제품 버전: Visual Studio
원래 KB 번호: 322022
IEnumerator 인터페이스
IEnumerable
및 IEnumerator
는 자주 함께 사용됩니다. 이러한 인터페이스는 유사하지만(이름이 비슷하지만) 용도가 다릅니다.
인터페이스는 IEnumerator
클래스 내부인 컬렉션에 대한 반복 기능을 제공합니다. IEnumerator
에는 다음 세 가지 메서드를 구현해야 합니다.
MoveNext
컬렉션 인덱스를 1씩 증가시키고 컬렉션의 끝에 도달했는지 여부를 나타내는 bool을 반환하는 메서드입니다.Reset
컬렉션 인덱스를 초기 값 -1로 다시 설정하는 메서드입니다. 이렇게 하면 열거자가 무효화됩니다.Current
에서 현재 개체position
를 반환하는 메서드입니다.public bool MoveNext() { position++; return (position < carlist.Length); } public void Reset() { position = -1; } public object Current { get { return carlist[position];} }
IEnumerable 인터페이스
인터페이스는 IEnumerable
반복을 foreach
지원합니다. IEnumerable
에서는 메서드를 구현해야 합니다 GetEnumerator
.
public IEnumerator GetEnumerator()
{
return (IEnumerator)this;
}
어떤 인터페이스를 사용해야 하는가?
처음에는 이러한 인터페이스를 사용하는 것이 혼란스러울 수 있습니다. 인터페이스는 IEnumerator
클래스의 컬렉션 형식 개체를 반복합니다. 인터페이스는 IEnumerable
루프를 사용하여 열거형을 허용합니다 foreach
. 그러나 인터페이스의 메서드는 GetEnumerator
IEnumerable
인터페이스를 반환합니다 IEnumerator
. 따라서 를 구현 IEnumerable
하려면 도 구현 IEnumerator
해야 합니다. 를 구현IEnumerator
하지 않으면 의 메서드 IEnumerable
에서 GetEnumerator
인터페이스로 반환 값을 캐스팅할 IEnumerator
수 없습니다.
요약하면 를 사용 IEnumerable
하려면 클래스가 를 구현 IEnumerator
해야 합니다. 에 대한 foreach
지원을 제공하려면 두 인터페이스를 모두 구현합니다.
단계별 예제
다음 예제에서는 이러한 인터페이스를 사용하는 방법을 보여 줍니다. 이 예제 IEnumerator
에서 및 IEnumerable
인터페이스는 라는 cars
클래스에서 사용됩니다. 클래스에는 cars
개체의 내부 배열이 car
있습니다. 클라이언트 애플리케이션은 이러한 두 인터페이스의 구현으로 인해 구문을 사용하여 foreach
이 내부 배열을 열거할 수 있습니다.
Visual C#에서 새 콘솔 애플리케이션 프로젝트를 만들려면 다음 단계를 수행합니다.
- Microsoft Visual Studio .NET 또는 Visual Studio를 시작합니다.
- 파일 메뉴에서 새로 만들기를 가리킨 다음 프로젝트를 클릭합니다.
- 프로젝트 유형에서 Visual C# 프로젝트를 선택한 다음 템플릿에서 콘솔 응용 프로그램을 선택합니다.
- 이름 상자에 ConsoleEnum을 입력합니다.
Class1.cs 이름을 host.cs 이름을 바꾼 다음 host.cs 코드를 다음 코드로 바꿉니다.
using System; namespace ConsoleEnum { class host { [STAThread] static void Main(string[] args) { cars C = new cars(); Console.WriteLine("\nInternal Collection (Unsorted - IEnumerable,Enumerator)\n"); foreach(car c in C) Console.WriteLine(c.Make + "\t\t" + c.Year); Console.ReadLine(); } } }
프로젝트 메뉴에서 클래스 추가를 클릭한 다음 이름 상자에 car를 입력합니다.
car.cs 코드를 다음 코드로 바꿉 있습니다.
using System; using System.Collections; namespace ConsoleEnum { public class car { private int year; private string make; public car(string Make,int Year) { make=Make; year=Year; } public int Year { get {return year;} set {year=value;} } public string Make { get {return make;} set {make=value;} } }//end class }//end namespace
프로젝트 메뉴에서 클래스 추가를 클릭하여 프로젝트에 다른 클래스를 추가한 다음 이름 상자에 자동차를 입력합니다.
cars.cs 코드를 다음 코드로 바꿉 있습니다.
using System; using System.Collections; namespace ConsoleEnum { public class cars : IEnumerator,IEnumerable { private car[] carlist; int position = -1; //Create internal array in constructor. public cars() { carlist= new car[6] { new car("Ford",1992), new car("Fiat",1988), new car("Buick",1932), new car("Ford",1932), new car("Dodge",1999), new car("Honda",1977) }; } //IEnumerator and IEnumerable require these methods. public IEnumerator GetEnumerator() { return (IEnumerator)this; } //IEnumerator public bool MoveNext() { position++; return (position < carlist.Length); } //IEnumerable public void Reset() { position = -1; } //IEnumerable public object Current { get { return carlist[position];} } } }
프로젝트를 실행합니다.
콘솔 창에 다음 출력이 표시됩니다.
Ford 1992
Fiat 1988
Buick 1932
Ford 1932
Dodge 1999
Honda 1977
모범 사례
이 문서의 예제는 이러한 인터페이스의 사용을 더 잘 설명하기 위해 가능한 한 간단하게 유지됩니다. 코드를 보다 강력하게 만들고 코드가 현재 모범 사례 지침을 사용하도록 하려면 다음과 같이 코드를 수정합니다.
- 여러 열거자를 만들 수 있도록 중첩 클래스에서 구현
IEnumerator
합니다. - 의
IEnumerator
메서드에 대한Current
예외 처리를 제공합니다. 컬렉션의 내용이 변경되면 메서드가reset
호출됩니다. 따라서 현재 열거자가 무효화되고 예외가 발생합니다IndexOutOfRangeException
. 다른 상황에서도 이 예외가 발생할 수 있습니다. 따라서 이 예외를Try...Catch
catch하고 예외를 발생하도록 블록을 구현합니다InvalidOperationException
.
using System;
using System.Collections;
namespace ConsoleEnum
{
public class cars : IEnumerable
{
private car[] carlist;
//Create internal array in constructor.
public cars()
{
carlist= new car[6]
{
new car("Ford",1992),
new car("Fiat",1988),
new car("Buick",1932),
new car("Ford",1932),
new car("Dodge",1999),
new car("Honda",1977)
};
}
//private enumerator class
private class MyEnumerator:IEnumerator
{
public car[] carlist;
int position = -1;
//constructor
public MyEnumerator(car[] list)
{
carlist=list;
}
private IEnumerator getEnumerator()
{
return (IEnumerator)this;
}
//IEnumerator
public bool MoveNext()
{
position++;
return (position < carlist.Length);
}
//IEnumerator
public void Reset()
{
position = -1;
}
//IEnumerator
public object Current
{
get
{
try
{
return carlist[position];
}
catch (IndexOutOfRangeException)
{
throw new InvalidOperationException();
}
}
}
} //end nested class
public IEnumerator GetEnumerator()
{
return new MyEnumerator(carlist);
}
}
}
피드백
https://aka.ms/ContentUserFeedback
출시 예정: 2024년 내내 콘텐츠에 대한 피드백 메커니즘으로 GitHub 문제를 단계적으로 폐지하고 이를 새로운 피드백 시스템으로 바꿀 예정입니다. 자세한 내용은 다음을 참조하세요.다음에 대한 사용자 의견 제출 및 보기