简体   繁体   English

System.Reflection.Emit - 如果语句生成

[英]System.Reflection.Emit - If Statement Generation

I'm trying to learn how If statements are generated with ILGenerator in C#. 我正在尝试学习如何在C#中使用ILGenerator生成If语句。

Here's my code: (ilg is an ILGenerator) 这是我的代码:(ilg是ILGenerator)

ilg.Emit(OpCodes.Ldc_I4_1);
Label start = ilg.DefineLabel();
ilg.Emit(OpCodes.Brfalse, start);
ilg.Emit(OpCodes.Ldstr, "Hello");
ilg.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
ilg.MarkLabel(start);

Some notes: 一些说明:

  • Alone, calling Console.WriteLine works perfectly. 独自调用Console.WriteLine完美运行。
  • This is the error that I get when I run the generated exe: 这是我运行生成的exe时得到的错误:

Unhandled Exception: System.InvalidProgramException: Common Language Runtime detected an invalid program. 未处理的异常:System.InvalidProgramException:公共语言运行时检测到无效的程序。 at Testing.Test.Main(String[] ) 在Testing.Test.Main(String [])

You code works almost fine, you just forgot to put OpCodes.Ret at end, see the code that works: 你的代码工作得很好,你只是忘了把OpCodes.Ret放到最后,看看有效的代码:

public static void Main(string[] args)
{
    var dynamicMethod = new DynamicMethod("PrintHello", typeof(void), null);
    var ilGenerator = dynamicMethod.GetILGenerator();
    ilGenerator.Emit(OpCodes.Ldc_I4_1);
    var toEnd = ilGenerator.DefineLabel();
    ilGenerator.Emit(OpCodes.Brfalse, toEnd);
    ilGenerator.Emit(OpCodes.Ldstr, "Hello");
    ilGenerator.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
    ilGenerator.MarkLabel(toEnd);
    ilGenerator.Emit(OpCodes.Ret);

    var @delegate = (Action)dynamicMethod.CreateDelegate(typeof(Action));
    @delegate();
}

Then you'll have this output 那你就有了这个输出

Hello 你好

If you comment this line ilGenerator.Emit(OpCodes.Ret); 如果你评论这行ilGenerator.Emit(OpCodes.Ret); you will get this exception 你会得到这个例外

System.InvalidProgramException : Common Language Runtime detected an invalid program. System.InvalidProgramException :公共语言运行时检测到无效程序。

Remember, every method in C# must have the OpCode.Ret 请记住,C#中的每个方法都必须具有OpCode.Ret

If your Main method is empty, like this 如果你的Main方法是空的,就像这样

public static void Main(string[] args)
{
}

The IL generated (in debug mode, without optimization) will be this 生成的IL(在调试模式下,没有优化)将是这样

.method public hidebysig static void Main (string[] args) cil managed 
{
    // Method begins at RVA 0x2050
    // Code size 2 (0x2)
    .maxstack 8
    .entrypoint

    IL_0000: nop
    IL_0001: ret
} // end of method Program::Main

The IL generated (in release mode, with optimization) will be this 生成的IL(在发布模式下, 具有优化)将是这样

.method public hidebysig static void Main (string[] args) cil managed 
{
    // Method begins at RVA 0x2050
    // Code size 1 (0x1)
    .maxstack 8
    .entrypoint

    IL_0000: ret
} // end of method Program::Main

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM