2015-08-21 2 views
2

Я совершенно новой для IL, но, как я знаю, MoveNext должен быть вызван до Current, позволяет сказать, что у нас есть такое Еогеасп заявление:Почему IEnumerator.MoveNext вызывается перед GetCurrent?

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

Смежные вопросы