Thinking about the differences between foreach, while and goto a few weeks ago, I wrote this test code. All methods will be compiled into the same IL (the other is the variable name in the foreach version). In debug mode, several NOP statements will be in different positions.
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 the comment by @Eric ...
I have extended for , while , 'goto' and foreach with shared arrays. The for each statement now uses a pointer to an array. Arrays of objects and strings expand similarly. Objects will remove the box that occurs before the method is called in Console.WriteLine and Strings will replace T item and T[] copy... with char item and string copy... respectively. Note that the critical section is no longer needed because the one-time counter is no longer used.
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; }
Matthew Whited Mar 15 '10 at 14:01 2010-03-15 14:01
source share