ILGenerator
не очень продвинутый, если вы используете перегрузку Emit(OpCode, Int32)
, это поместит весь int32
в поток команд, независимо от того, является ли код операции Ldc_I4
(который на самом деле требует 4 байта сразу) или Ldc_I4_S
(чего нет).
Поэтому обязательно используйте правильную перегрузку:
ilGenerator.Emit(OpCodes.Ldc_I4_S, (byte)120);
Леммы для кодов операций в документации указывают, какую перегрузку Emit
следует использовать.
В справочном источнике , Emit
с аргументом int
делает это:
public virtual void Emit(OpCode opcode, int arg)
{
// Puts opcode onto the stream of instructions followed by arg
EnsureCapacity(7);
InternalEmit(opcode);
PutInteger4(arg);
}
Где PutInteger4
записывает четыре байта в байтовый массив, в котором построен IL.
В документации Emit
говорится, что дополнительные байты будут Nop
инструкциями, но это только если они фактически равны нулю. Если передаваемое значение «более неправильное» (с старшими байтами, отличными от нуля), то последствия могут быть хуже, от недопустимых кодов операций до операций, которые слегка искажают результаты.