for, foreach, while, goto의 차이점을 몇 주 전에 궁금하게 생각하면서이 테스트 코드를 작성했습니다. 모든 메소드는 동일한 IL (foreach 버전의 다른 변수 이름)로 컴파일됩니다. 디버그 모드에서 일부 NOP 문은 다른 위치에 있습니다. 에릭의 코멘트 @ 당
static void @for<T>(IEnumerable<T> input)
{
T item;
using (var e = input.GetEnumerator())
for (; e.MoveNext();)
{
item = e.Current;
Console.WriteLine(item);
}
}
static void @foreach<T>(IEnumerable<T> input)
{
foreach (var item in input)
Console.WriteLine(item);
}
static void @while<T>(IEnumerable<T> input)
{
T item;
using (var e = input.GetEnumerator())
while (e.MoveNext())
{
item = e.Current;
Console.WriteLine(item);
}
}
static void @goto<T>(IEnumerable<T> input)
{
T item;
using (var e = input.GetEnumerator())
{
goto check;
top:
item = e.Current;
Console.WriteLine(item);
check:
if (e.MoveNext())
goto top;
}
}
static void @gotoTry<T>(IEnumerable<T> input)
{
T item;
var e = input.GetEnumerator();
try
{
goto check;
top:
item = e.Current;
Console.WriteLine(item);
check:
if (e.MoveNext())
goto top;
}
finally
{
if (e != null)
e.Dispose();
}
}
...
나는 일반적인 배열 for
, while
, '고토'와 foreach
을 확장했다. 이제 for each
문은 배열에 대한 인덱서를 사용합니다. 객체 배열과 문자열도 비슷한 방식으로 확장됩니다. Console.WriteLine 및 Strings에 대한 메서드 호출이 T item
및 T[] copy...
을 char item
및 string copy...
으로 각각 대체하기 전에 발생하는 복싱을 제거합니다. 일회용 열거자를 더 이상 사용하지 않기 때문에 중요 섹션을 더 이상 필요하지 않습니다.
static void @for<T>(T[] input)
{
T item;
T[] copy = input;
for (int i = 0; i < copy.Length; i++)
{
item = copy[i];
Console.WriteLine(item);
}
}
static void @foreach<T>(T[] input)
{
foreach (var item in input)
Console.WriteLine(item);
}
static void @while<T>(T[] input)
{
T item;
T[] copy = input;
int i = 0;
while (i < copy.Length)
{
item = copy[i];
Console.WriteLine(item);
i++;
}
}
static void @goto<T>(T[] input)
{
T item;
T[] copy = input;
int i = 0;
goto check;
top:
item = copy[i];
Console.WriteLine(item);
i++;
check:
if (i < copy.Length)
goto top;
}
중복 : http://stackoverflow.com/questions/1632810/how-does-foreach-work-when-looping-through-function-results –