У меня есть следующие функции:Анализ MSIL код генерируется из C#
public string MyPhrase(int val)
{
if ((val %3 == 0) && (val % 6 == 0))
return "Fizz Bang";
if (val % 3 == 0)
return "Fizz";
if (val % 6 == 0)
return "Bang";
return "";
}
После компиляции этого и просмотра его с ILDASM, я получаю этот выход:
IL_0000: ldarg.1
IL_0001: ldc.i4.3
IL_0002: rem
IL_0003: brtrue.s IL_0010
IL_0005: ldarg.1
IL_0006: ldc.i4.6
IL_0007: rem
IL_0008: brtrue.s IL_0010
IL_000a: ldstr "Fizz Bang"
IL_000f: ret
IL_0010: ldarg.1
IL_0011: ldc.i4.3
IL_0012: rem
IL_0013: brtrue.s IL_001b
IL_0015: ldstr "Fizz"
IL_001a: ret
IL_001b: ldarg.1
IL_001c: ldc.i4.6
IL_001d: rem
IL_001e: brtrue.s IL_0026
IL_0020: ldstr "Bang"
IL_0025: ret
IL_0026: ldstr ""
IL_002b: ret
Глядя на this page, brtrue
будет если true. Меня смущает линия IL_0003
. Он говорит, что он должен перейти к строке IL_0010
, если это правда. В моем коде C#, хотя, я использую &&
для сравнения двух выражений, прежде чем мой поток программы должен перейти к следующему if
. Это кажется обратным. Из опубликованного кода MSIL кажется, что он проверяет, действительно ли моя операция верна, и если это так, ее переход к моему следующему блоку if
, что было бы логически неверным. Может кто-нибудь объяснить, что мне не хватает?
Интересно, почему вы выбрали этот пример. Не то, чтобы компилятор это понял, но «взрыва» никогда нельзя было вернуть, не так ли? Если 'val' были делятся на' 6', то наверняка он был бы делимым на '3'? –
@JeppeStigNielsen Действительно. Вот почему традиционно проблема FizzBang использует 3 и 5, а не 3 и 6. – verdesmarald
@JeppeStigNielsen - Фактическая функция вообще не полезна. Я просто анализировал код MSIL для удовольствия. – Icemanind