2015-08-21 56 views
2

我完全新的IL,但我知道MoveNext應該Current之前被調用,可以說,我們有這樣的foreach語句:爲什麼在GetCurrent之前調用IEnumerator.MoveNext?

foreach (var i in Enumerable.Empty<string>()) 
{   
} 

如果我們看一下產生IL我們會看到,目前實際上是第一個叫:

IL_0014: br.s  IL_001f 
IL_0016: ldloc.1 
IL_0017: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1<string>::get_Current() 
IL_001c: stloc.0 
IL_001d: nop 
IL_001e: nop 
IL_001f: ldloc.1 
IL_0020: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() 
IL_0025: stloc.2 
IL_0026: ldloc.2 
IL_0027: brtrue.s IL_0016 
IL_0029: leave.s IL_003b 

問題是爲什麼?

+1

電流不會首先調用,在IL_0014是無條件轉移到IL_001f。 – thehennyy

+0

爲什麼我會減去? –

回答

4
IL_0014: br.s  IL_001f 

根據MSDN,br.s

無條件地將控制到目標指令(短形式)。

引用的地址是調用MoveNext的說明。

IL_001f: ldloc.1 
IL_0020: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() 
+0

他們爲什麼需要這種無條件轉移?順序編寫它不是更有意義嗎? –

+2

@AndriusCepaitis它不是由人寫的,它是由編譯器自動生成的。我不認爲*更有意義*是它的優先事項 – Eser

相關問題