Извлеките его, и он, вероятно, станет более ясным.
var myCollection = new List<object>();
var skipped = myCollection.Skip(1);
foreach (var i in skipped) {
Console.WriteLine(i.ToString());
}
Так что пропущено только IEnumerable
, которое теперь перечисляет foreach
.
Вот что выглядит IL как и в этом случае:
IL_0000: newobj System.Collections.Generic.List<System.Object>..ctor
IL_0005: stloc.0 // myCollection
IL_0006: ldloc.0 // myCollection
IL_0007: ldc.i4.1
IL_0008: call System.Linq.Enumerable.Skip
IL_000D: stloc.1 // skipped
IL_000E: ldloc.1 // skipped
IL_000F: callvirt System.Collections.Generic.IEnumerable<System.Object>.GetEnumerator
IL_0014: stloc.3 // CS$5$0000
IL_0015: br.s IL_0029
IL_0017: ldloc.3 // CS$5$0000
IL_0018: callvirt System.Collections.Generic.IEnumerator<System.Object>.get_Current
IL_001D: stloc.2 // i
IL_001E: ldloc.2 // i
IL_001F: callvirt System.Object.ToString
IL_0024: call System.Console.WriteLine
IL_0029: ldloc.3 // CS$5$0000
IL_002A: callvirt System.Collections.IEnumerator.MoveNext
IL_002F: brtrue.s IL_0017
IL_0031: leave.s IL_003D
IL_0033: ldloc.3 // CS$5$0000
IL_0034: brfalse.s IL_003C
IL_0036: ldloc.3 // CS$5$0000
IL_0037: callvirt System.IDisposable.Dispose
IL_003C: endfinally
IL для вашего кода выглядит схоже:
var myCollection = new List<object>();
foreach (var i in myCollection.Skip(1)) {
Console.WriteLine(i.ToString());
}
IL_0000: newobj System.Collections.Generic.List<System.Object>..ctor
IL_0005: stloc.0 // myCollection
IL_0006: ldloc.0 // myCollection
IL_0007: ldc.i4.1
IL_0008: call System.Linq.Enumerable.Skip <-- 1 Call to .Skip() outside the loop.
IL_000D: callvirt System.Collections.Generic.IEnumerable<System.Object>.GetEnumerator
IL_0012: stloc.2 // CS$5$0000
IL_0013: br.s IL_0027
IL_0015: ldloc.2 // CS$5$0000
IL_0016: callvirt System.Collections.Generic.IEnumerator<System.Object>.get_Current
IL_001B: stloc.1 // i
IL_001C: ldloc.1 // i
IL_001D: callvirt System.Object.ToString
IL_0022: call System.Console.WriteLine
IL_0027: ldloc.2 // CS$5$0000
IL_0028: callvirt System.Collections.IEnumerator.MoveNext
IL_002D: brtrue.s IL_0015
IL_002F: leave.s IL_003B
IL_0031: ldloc.2 // CS$5$0000
IL_0032: brfalse.s IL_003A
IL_0034: ldloc.2 // CS$5$0000
IL_0035: callvirt System.IDisposable.Dispose
IL_003A: endfinally
У него все еще есть один вызов .Skip ().