foreach
루프 를 사용할 수있는 클래스 유형은 무엇입니까?
답변:
실제로 엄밀히 말하면 메서드와 속성으로 무언가를 반환 foreach
하는 공용 GetEnumerator()
메서드 만 사용해야합니다 . 그러나 가장 일반적인 이것의 의미는 구현이 뭔가 "입니다 / , 반환 /을 .bool MoveNext()
? Current {get;}
IEnumerable
IEnumerable<T>
IEnumerator
IEnumerator<T>
암시으로이 구현하는 것을 포함 ICollection
/ ICollection<T>
등 같은 아무것도 Collection<T>
, List<T>
, 배열 ( T[]
) 등의 표준 "데이터 수집"그래서 일반적으로 지원됩니다 foreach
.
첫 번째 요점을 증명하기 위해 다음이 잘 작동합니다.
using System;
class Foo {
public int Current { get; private set; }
private int step;
public bool MoveNext() {
if (step >= 5) return false;
Current = step++;
return true;
}
}
class Bar {
public Foo GetEnumerator() { return new Foo(); }
}
static class Program {
static void Main() {
Bar bar = new Bar();
foreach (int item in bar) {
Console.WriteLine(item);
}
}
}
어떻게 작동합니까?
foreach(int i in obj) {...}
좀 같은 foreach 루프는 다음과 같습니다.
var tmp = obj.GetEnumerator();
int i; // up to C# 4.0
while(tmp.MoveNext()) {
int i; // C# 5.0
i = tmp.Current;
{...} // your code
}
그러나 변형이 있습니다. 예를 들어 열거 자 (tmp)가를 지원하는 경우이 IDisposable
역시 사용됩니다 (와 유사 using
).
차분 참고 선언 "의 위치에서 int i
" 내부 (C # 5.0) 대에서 외부 루프 (C # 4.0 업). i
코드 블록 내에서 익명 메서드 / 람다 를 사용 하는 경우 중요합니다 . 그러나 그것은 또 다른 이야기입니다 ;-p
for-loop
(IL로 작업 할 때 이것을 볼 수 있습니다).
에서 MSDN :
이
foreach
문 은 배열 또는 개체 컬렉션의 각 요소에 대해 포함 된 문 그룹을 반복합니다 . 이foreach
문은 원하는 정보를 얻기 위해 컬렉션을 반복하는 데 사용되지만 예측할 수없는 부작용을 방지하기 위해 컬렉션의 내용을 변경하는 데 사용해서는 안됩니다. (강조 광산)
따라서 배열이있는 경우 다음과 같이 foreach 문을 사용하여 배열을 반복 할 수 있습니다.
int[] fibarray = new int[] { 0, 1, 2, 3, 5, 8, 13 };
foreach (int i in fibarray)
{
System.Console.WriteLine(i);
}
다음 List<T>
과 같이 컬렉션 을 반복하는 데 사용할 수도 있습니다 .
List<string> list = new List<string>();
foreach (string item in list)
{
Console.WriteLine(item);
}
블로그 게시물 Duck Notation 에 따르면 덕 타이핑이 사용됩니다.
문서는 다음과 같습니다. 컬렉션 개체가 있는 배열을 사용한 본문
"컬렉션 요소의 유형은 식별자 유형으로 변환 가능해야합니다"라는 점에 유의해야합니다. 이것은 때때로 컴파일 타임에 확인할 수 없으며 인스턴스 유형이 참조 유형에 할당되지 않는 경우 런타임 예외를 생성 할 수 있습니다.
오렌지와 같은 과일 바구니에 Apple이 아닌 경우 런타임 예외가 생성됩니다.
List<Fruit> fruitBasket = new List<Fruit>() { new Apple(), new Orange() };
foreach(Apple a in fruitBasket)
이렇게하면 Enumerable.OfType을 사용하여 목록을 Apple로만 안전하게 필터링합니다.
foreach(Apple a in fruitBasket.OfType<Apple>() )
IList<ListItem> illi = new List<ListItem>();
ListItem li = null;
foreach (HroCategory value in listddlsubcategory)
{
listddlsubcategoryext = server.getObjectListByColumn(typeof(HroCategory), "Parentid", value.Id);
li = new ListItem();
li.Text = value.Description;
li.Value = value.Id.ToString();
illi.Add(li);
IList<ListItem> newilli = new List<ListItem>();
newilli = SubCatagoryFunction(listddlsubcategoryext, "-->");
foreach (ListItem c in newilli)
{
illi.Add(c);
}
}
이 주제에 대한 유용한 정보는 MSDN 에서도 찾을 수 있습니다 . 그 기사에서 본질을 취하십시오 :
foreach 키워드는 컬렉션을 열거하고 컬렉션의 각 요소에 대해 한 번씩 포함 된 문을 실행합니다.
foreach (var item in collection)
{
Console.WriteLine(item.ToString());
}
컴파일러는 위의 예제에 표시된 foreach 루프를 다음 구문과 유사한 것으로 변환합니다.
IEnumerator<int> enumerator = collection.GetEnumerator();
while (enumerator.MoveNext())
{
var item = enumerator.Current;
Console.WriteLine(item.ToString());
}