Emit常用Opcodes指令使用方法(含实例)

本人是从0开始学习Emit的,在学习过程中比较困扰我的就是有很多指令不理解、不会用,查了很多资料最终算是搞明白了,记录下来供大家参考。
除了在网上查资料外,学习Emit和MSIL的另一种方式是.Net Reflector和ildasm.exe配合使用,.Net Reflector能把MSIL代码转换成C#代码(Emit中的Opcodes指令与MSIL指令对应),ildasm.exe能把C#代码转换为MSIL,当想用Emit实现某一功能但是不知道怎么写时,可以先把该功能的C#代码写出来,再用ildasm.exe将其转换成MSIL,最后根据转化生成的MSIL代码的逻辑来写Emit代码,这个很实用。

【非静态】Ldstr+OpCodes.Ldarg_1

Emit代码:

public class StudyOpCodes
{
    public void Test()
    {
        AssemblyName assemblyName = new AssemblyName("Study");
        AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
        ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("StudyModule", "StudyOpCodes.dll");
        TypeBuilder typeBuilder = moduleBuilder.DefineType("StudyOpCodes", TypeAttributes.Public);
        MethodBuilder showMethod = typeBuilder.DefineMethod("Show", MethodAttributes.Public, null, new Type[] { typeof(int), typeof(string) });

        ILGenerator ilOfShow = showMethod.GetILGenerator();
        //非静态方法参数索引从1开始
        ilOfShow.Emit(OpCodes.Ldstr, "姓名:{1} 年龄:{0}");
        ilOfShow.Emit(OpCodes.Ldarg_1);
        ilOfShow.Emit(OpCodes.Ldarg_2);
        ilOfShow.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(int), typeof(string) }));
        ilOfShow.Emit(OpCodes.Pop);
        ilOfShow.Emit(OpCodes.Ret);
        Type t = typeBuilder.CreateType();
        assemblyBuilder.Save("StudyOpCodes.dll"); 
    }
}    

.Net Reflector转化后的C#代码:

public class StudyOpCodes
{
    // Methods
    public void Show(int num1, string text1)
    {
        string.Format("姓名:{1} 年龄:{0}", num1, text1);
    }
}

【静态】Ldstr和OpCodes.Ldarg_1

Emit代码:

public class StudyOpCodes
{
    public void Test()
    {
        AssemblyName assemblyName = new AssemblyName("Study");
        AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
        ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("StudyModule", "StudyOpCodes.dll");
        TypeBuilder typeBuilder = moduleBuilder.DefineType("StudyOpCodes", TypeAttributes.Public);
        MethodBuilder showMethod = typeBuilder.DefineMethod("Show", MethodAttributes.Public | MethodAttributes.Static, null, new Type[] { typeof(int), typeof(string) });

        ILGenerator ilOfShow = showMethod.GetILGenerator();
        ilOfShow.Emit(OpCodes.Ldstr, "姓名:{1} 年龄:{0}");
        //静态方法必参数索引从0开始
        ilOfShow.Emit(OpCodes.Ldarg_0);
        ilOfShow.Emit(OpCodes.Ldarg_1);
        ilOfShow.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(int), typeof(string) }));
        ilOfShow.Emit(OpCodes.Pop);
        ilOfShow.Emit(OpCodes.Ret);
        Type t = typeBuilder.CreateType();
        assemblyBuilder.Save("StudyOpCodes.dll");
    }
}    

.Net Reflector转化后的C#代码:

public class StudyOpCodes
{
    // Methods
    public static void Show(int num1, string text1)
    {
        string.Format("姓名:{1} 年龄:{0}", num1, text1);
    }
}

Ldc_I4和Ldc_I8

Emit代码:

public class StudyOpCodes
{
    public void Test()
    {
        AssemblyName assemblyName = new AssemblyName("Study");
        AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
        ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("StudyModule", "StudyOpCodes.dll");
        TypeBuilder typeBuilder = moduleBuilder.DefineType("StudyOpCodes", TypeAttributes.Public);
        MethodBuilder showMethod = typeBuilder.DefineMethod("Show", MethodAttributes.Public, null, new Type[] { typeof(int), typeof(string) });

        #region Ldc_I4
        ILGenerator ilOfShow = showMethod.GetILGenerator();
        ilOfShow.Emit(OpCodes.Ldstr, "姓名:{1} 年龄:{0}");
        //typeof(int)指的是Int32,数字默认是Int32类型
        ilOfShow.Emit(OpCodes.Ldc_I4, 18);
        //非静态方法参数索引从1开始
        ilOfShow.Emit(OpCodes.Ldarg_2);
        ilOfShow.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(int), typeof(string) }));
        ilOfShow.Emit(OpCodes.Pop);
        ilOfShow.Emit(OpCodes.Ret);
        #endregion

        #region Ldc_I8
        ILGenerator ilOfShow = showMethod.GetILGenerator();
        ilOfShow.Emit(OpCodes.Ldstr, "姓名:{1} 年龄:{0}");
        //typeof(int)指的是Int32,数字默认是Int32类型
        ilOfShow.Emit(OpCodes.Ldc_I8, Convert.ToInt64(18));
        //非静态方法参数索引从1开始
        ilOfShow.Emit(OpCodes.Ldarg_2);
        ilOfShow.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(Int64), typeof(string) }));
        ilOfShow.Emit(OpCodes.Pop);
        ilOfShow.Emit(OpCodes.Ret);
        #endregion

        Type t = typeBuilder.CreateType();
        assemblyBuilder.Save("StudyOpCodes.dll"); 
    }
}    

.Net Reflector转化后的C#代码:

//Ldc_I4
public class StudyOpCodes
{
    // Methods
    public void Show(int, string text1)
    {
        string.Format("姓名:{1} 年龄:{0}", 0x12, text1);
    }
}
//Ldc_I8
public class StudyOpCodes
{
    // Methods
    public void Show(int, string text1)
    {
        string.Format("姓名:{1} 年龄:{0}", 0x12L, text1);
    }
}

Ldc_R4和Ldc_R8

Emit代码:

public class StudyOpCodes
{
    public void Test()
    {
        AssemblyName assemblyName = new AssemblyName("Study");
        AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
        ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("StudyModule", "StudyOpCodes.dll");
        TypeBuilder typeBuilder = moduleBuilder.DefineType("StudyOpCodes", TypeAttributes.Public);
        MethodBuilder showMethod = typeBuilder.DefineMethod("Show", MethodAttributes.Public, null, new Type[] { typeof(int), typeof(string) });

        #region Ldc_R4
        ILGenerator ilOfShow = showMethod.GetILGenerator();
        ilOfShow.Emit(OpCodes.Ldstr, "姓名:{1} 年龄:{0}");
        //12.3默认是Double类型
        ilOfShow.Emit(OpCodes.Ldc_R4, (float)12.3);
        //非静态方法参数索引从1开始
        ilOfShow.Emit(OpCodes.Ldarg_2);
        ilOfShow.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(float), typeof(string) }));
        ilOfShow.Emit(OpCodes.Pop);
        ilOfShow.Emit(OpCodes.Ret); 
        #endregion

        #region Ldc_R8
        ILGenerator ilOfShow = showMethod.GetILGenerator();
        ilOfShow.Emit(OpCodes.Ldstr, "姓名:{1} 年龄:{0}");
        //12.3默认是Double类型
        ilOfShow.Emit(OpCodes.Ldc_R8, 12.3);
        //非静态方法参数索引从1开始
        ilOfShow.Emit(OpCodes.Ldarg_2);
        ilOfShow.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(double), typeof(string) }));
        ilOfShow.Emit(OpCodes.Pop);
        ilOfShow.Emit(OpCodes.Ret);  
        #endregion

        Type t = typeBuilder.CreateType();
        assemblyBuilder.Save("StudyOpCodes.dll"); 
    }
}    

.Net Reflector转化后的C#代码:

//Ldc_R4
public class StudyOpCodes
{
    // Methods
    public void Show(int, string text1)
    {
        string.Format("姓名:{1} 年龄:{0}", 12.3f, text1);
    }
}
//Ldc_R8
public class StudyOpCodes
{
    // Methods
    public void Show(int, string text1)
    {
        string.Format("姓名:{1} 年龄:{0}", 12.3, text1);
    }
}

Ldfld和Stfld

Emit代码:

public class StudyOpCodes
{
    public void Test()
    {
        AssemblyName assemblyName = new AssemblyName("Study");
        AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
        ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("StudyModule", "StudyOpCodes.dll");
        TypeBuilder typeBuilder = moduleBuilder.DefineType("StudyOpCodes", TypeAttributes.Public);
        MethodBuilder showMethod = typeBuilder.DefineMethod("Show", MethodAttributes.Public, null, new Type[] { typeof(int), typeof(string) });
        FieldBuilder fieldName = typeBuilder.DefineField("Name", typeof(string), FieldAttributes.Private);

        #region Ldfld
        ILGenerator ilOfShow = showMethod.GetILGenerator();
        //非静态方法参数索引从1开始
        ilOfShow.Emit(OpCodes.Ldstr, "姓名:{1} 年龄:{0}");
        ilOfShow.Emit(OpCodes.Ldc_I4, 18);
        //OpCodes.Ldfld之前必须OpCodes.Ldarg_0
        ilOfShow.Emit(OpCodes.Ldarg_0);
        ilOfShow.Emit(OpCodes.Ldfld, fieldName);
        ilOfShow.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(int), typeof(string) }));
        ilOfShow.Emit(OpCodes.Pop);
        ilOfShow.Emit(OpCodes.Ret);
        #endregion

        #region Stfld
        ILGenerator ilOfShow = showMethod.GetILGenerator();
        //*非静态方法参数索引从1开始
        //OpCodes.Stfld之前必须OpCodes.Ldarg_0   
        //this.Name = text1;
        ilOfShow.Emit(OpCodes.Ldarg_0);
        ilOfShow.Emit(OpCodes.Ldarg_2);
        ilOfShow.Emit(OpCodes.Stfld, fieldName);
        //this.Name = "guo";
        ilOfShow.Emit(OpCodes.Ldarg_0);
        ilOfShow.Emit(OpCodes.Ldstr, "guo");
        ilOfShow.Emit(OpCodes.Stfld, fieldName);
        ////text1.Name = (string) this;
        //ilOfShow.Emit(OpCodes.Ldarg_2);
        //ilOfShow.Emit(OpCodes.Ldarg_0);
        //ilOfShow.Emit(OpCodes.Stfld, fieldName);
        ////堆栈为空
        //ilOfShow.Emit(OpCodes.Ldarg_2);
        //ilOfShow.Emit(OpCodes.Stfld, fieldName);
        ////堆栈为空
        //ilOfShow.Emit(OpCodes.Ldstr,"guo");
        //ilOfShow.Emit(OpCodes.Stfld, fieldName);

        ilOfShow.Emit(OpCodes.Ldstr, "姓名:{1} 年龄:{0}");
        ilOfShow.Emit(OpCodes.Ldc_I4, 18);
        //OpCodes.Ldfld之前必须OpCodes.Ldarg_0
        ilOfShow.Emit(OpCodes.Ldarg_0);
        ilOfShow.Emit(OpCodes.Ldfld, fieldName);
        ilOfShow.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(int), typeof(string) }));
        ilOfShow.Emit(OpCodes.Pop);
        ilOfShow.Emit(OpCodes.Ret);
        #endregion

        Type t = typeBuilder.CreateType();
        assemblyBuilder.Save("StudyOpCodes.dll"); 
    }
}    

.Net Reflector转化后的C#代码:

//Ldfld
public class StudyOpCodes
{
    // Fields
    private string Name;

    // Methods
    public void Show(int, string)
    {
        string.Format("姓名:{1} 年龄:{0}", 0x12, this.Name);
    }
}
//Stfld
public class StudyOpCodes
{
    // Fields
    private string Name;

    // Methods
    public void Show(int, string text1)
    {
        this.Name = text1;
        this.Name = "guo";
        string.Format("姓名:{1} 年龄:{0}", 0x12, this.Name);
    }
}

Ldsfld和Stsfld

Emit代码:

public class StudyOpCodes
{
    public void Test()
    {
        AssemblyName assemblyName = new AssemblyName("Study");
        AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
        ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("StudyModule", "StudyOpCodes.dll");
        TypeBuilder typeBuilder = moduleBuilder.DefineType("StudyOpCodes", TypeAttributes.Public);
        MethodBuilder showMethod = typeBuilder.DefineMethod("Show", MethodAttributes.Public, null, new Type[] { typeof(int), typeof(string) });
        FieldBuilder fieldName = typeBuilder.DefineField("Name", typeof(string), FieldAttributes.Private | FieldAttributes.Static);

        #region Ldsfld
        ILGenerator ilOfShow = showMethod.GetILGenerator();
        ilOfShow.Emit(OpCodes.Ldstr, "姓名:{1} 年龄:{0}");
        ilOfShow.Emit(OpCodes.Ldc_I4, 18);
        //*OpCodes.Ldsfld之前不能有OpCodes.Ldarg_0
        ilOfShow.Emit(OpCodes.Ldsfld, fieldName);
        ilOfShow.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(int), typeof(string) }));
        ilOfShow.Emit(OpCodes.Pop);
        ilOfShow.Emit(OpCodes.Ret);
        #endregion

        #region Stsfld
        ILGenerator ilOfShow = showMethod.GetILGenerator();
        //OpCodes.Stsfld之前不能有OpCodes.Ldarg_0,Name = text1;
        ilOfShow.Emit(OpCodes.Ldarg_2);
        ilOfShow.Emit(OpCodes.Stsfld, fieldName);
        //OpCodes.Stsfld之前不能有OpCodes.Ldarg_0,Name = "guo";
        ilOfShow.Emit(OpCodes.Ldstr, "guo");
        ilOfShow.Emit(OpCodes.Stsfld, fieldName);

        ilOfShow.Emit(OpCodes.Ldstr, "姓名:{1} 年龄:{0}");
        ilOfShow.Emit(OpCodes.Ldc_I4, 18);
        //OpCodes.Ldsfld之前不能有OpCodes.Ldarg_0
        ilOfShow.Emit(OpCodes.Ldsfld, fieldName);
        ilOfShow.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(int), typeof(string) }));
        ilOfShow.Emit(OpCodes.Pop);
        ilOfShow.Emit(OpCodes.Ret);
        #endregion

        Type t = typeBuilder.CreateType();
        assemblyBuilder.Save("StudyOpCodes.dll");
    }
}    

.Net Reflector转化后的C#代码:

//Ldsfld
public class StudyOpCodes
{
    // Fields
    private static string Name;

    // Methods
    public void Show(int, string)
    {
        string.Format("姓名:{1} 年龄:{0}", 0x12, Name);
    }
}
//Stsfld
public class StudyOpCodes
{
    // Fields
    private static string Name;

    // Methods
    public void Show(int, string text1)
    {
        Name = text1;
        Name = "guo";
        string.Format("姓名:{1} 年龄:{0}", 0x12, Name);
    }
}

Ldloc和Stloc

Emit代码:

public class StudyOpCodes
{
    public void Test()
    {
        AssemblyName assemblyName = new AssemblyName("Study");
        AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
        ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("StudyModule", "StudyOpCodes.dll");
        TypeBuilder typeBuilder = moduleBuilder.DefineType("StudyOpCodes", TypeAttributes.Public);
        MethodBuilder showMethod = typeBuilder.DefineMethod("Show", MethodAttributes.Public, null, new Type[] { typeof(int), typeof(string) });
        FieldBuilder fieldName = typeBuilder.DefineField("Name", typeof(string), FieldAttributes.Private | FieldAttributes.Static);

        #region Ldloc
        ILGenerator ilOfShow = showMethod.GetILGenerator();
        LocalBuilder localName = ilOfShow.DeclareLocal(typeof(string));
        ilOfShow.Emit(OpCodes.Ldstr, "姓名:{1} 年龄:{0}");
        ilOfShow.Emit(OpCodes.Ldc_I4, 18);
        //*OpCodes.Ldloc之前不能有OpCodes.Ldarg_0
        ilOfShow.Emit(OpCodes.Ldloc, localName);
        ilOfShow.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(int), typeof(string) }));
        ilOfShow.Emit(OpCodes.Pop);
        ilOfShow.Emit(OpCodes.Ret);
        #endregion

        #region Stloc
        ILGenerator ilOfShow = showMethod.GetILGenerator();
        LocalBuilder localName = ilOfShow.DeclareLocal(typeof(string));
        // OpCodes.Stloc之前不能有OpCodes.Ldarg_0
        ilOfShow.Emit(OpCodes.Ldarg_2);
        ilOfShow.Emit(OpCodes.Stloc, localName);
        // OpCodes.Stloc之前不能有OpCodes.Ldarg_0
        ilOfShow.Emit(OpCodes.Ldstr, "guo");
        ilOfShow.Emit(OpCodes.Stloc, localName);
        // 【静态字段】str=Name;
        ilOfShow.Emit(OpCodes.Ldsfld, fieldName);
        ilOfShow.Emit(OpCodes.Stloc, localName);
        // 【普通字段】str=this.Name;
        //ilOfShow.Emit(OpCodes.Ldarg_0);
        //ilOfShow.Emit(OpCodes.Ldfld, fieldName);
        //ilOfShow.Emit(OpCodes.Stloc, localName);

        ilOfShow.Emit(OpCodes.Ldstr, "姓名:{1} 年龄:{0}");
        ilOfShow.Emit(OpCodes.Ldc_I4, 18);
        //OpCodes.Ldloc之前不能有OpCodes.Ldarg_0
        ilOfShow.Emit(OpCodes.Ldloc, localName);
        ilOfShow.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(int), typeof(string) }));
        ilOfShow.Emit(OpCodes.Pop);
        ilOfShow.Emit(OpCodes.Ret);
        #endregion

        Type t = typeBuilder.CreateType();
        assemblyBuilder.Save("StudyOpCodes.dll"); 
    }
}    

.Net Reflector转化后的C#代码:

//Ldloc
public class StudyOpCodes
{
    // Fields
    private static string Name;

    // Methods
    public void Show(int, string)
    {
        string str;
        string.Format("姓名:{1} 年龄:{0}", 0x12, str);
    }
}
//Stloc
public class StudyOpCodes
{
    // Fields
    private static string Name;

    // Methods
    public void Show(int, string text1)
    {
        string name = text1;//此处的局部变量名之所以为name,是因为第三行赋值代码的原因,如果字段名为Address,那此处的局部变量名就会变成address
        name = "guo";
        name = Name;
        string.Format("姓名:{1} 年龄:{0}", 0x12, name);
    }
}

Box和Unbox

Emit代码:

public class StudyOpCodes
{
    public void Test()
    {
        AssemblyName assemblyName = new AssemblyName("Study");
        AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
        ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("StudyModule", "StudyOpCodes.dll");
        TypeBuilder typeBuilder = moduleBuilder.DefineType("StudyOpCodes", TypeAttributes.Public);
        MethodBuilder showMethod = typeBuilder.DefineMethod("Show", MethodAttributes.Public, null, new Type[] { typeof(int), typeof(string) });
        FieldBuilder fieldAge = typeBuilder.DefineField("objectAge", typeof(object), FieldAttributes.Private);

        #region Box
        ILGenerator ilOfShow = showMethod.GetILGenerator();
        //*此处的OpCodes.Ldarg_0是OpCodes.Stfld所需的
        ilOfShow.Emit(OpCodes.Ldarg_0);
        ilOfShow.Emit(OpCodes.Ldc_I4, 18);
        ilOfShow.Emit(OpCodes.Box, typeof(int));
        ilOfShow.Emit(OpCodes.Stfld, fieldAge);
        ilOfShow.Emit(OpCodes.Ret);
        #endregion

        #region Unbox
        ILGenerator ilOfShow = showMethod.GetILGenerator();
        LocalBuilder localAge = ilOfShow.DeclareLocal(typeof(int));
        //此处的OpCodes.Ldarg_0是OpCodes.Stfld所需的
        ilOfShow.Emit(OpCodes.Ldarg_0);
        ilOfShow.Emit(OpCodes.Ldc_I4, 18);
        ilOfShow.Emit(OpCodes.Box, typeof(int));
        ilOfShow.Emit(OpCodes.Stfld, fieldAge);
        //*此处的OpCodes.Ldarg_0是OpCodes.Ldfld所需的
        ilOfShow.Emit(OpCodes.Ldarg_0);
        ilOfShow.Emit(OpCodes.Ldfld, fieldAge);
        ilOfShow.Emit(OpCodes.Unbox, typeof(int));
        ilOfShow.Emit(OpCodes.Stloc, localAge);
        ilOfShow.Emit(OpCodes.Ret);
        #endregion

        Type t = typeBuilder.CreateType();
        assemblyBuilder.Save("StudyOpCodes.dll"); 
    }
}    

.Net Reflector转化后的C#代码:

//Box
public class StudyOpCodes
{
    // Fields
    private object objectAge;

    // Methods
    public void Show(int, string)
    {
        this.objectAge = 0x12;
    }
}
//Unbox
public class StudyOpCodes
{
    // Fields
    private object objectAge;

    // Methods
    public void Show(int, string)
    {
        this.objectAge = 0x12;
        int objectAge = (int) this.objectAge;
    }
}

Newobj

Emit代码:

public class StudyOpCodes
{
    public void Test()
    {
        AssemblyName assemblyName = new AssemblyName("Study");
        AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
        ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("StudyModule", "StudyOpCodes.dll");
        TypeBuilder typeBuilder = moduleBuilder.DefineType("StudyOpCodes", TypeAttributes.Public);
        MethodBuilder showMethod = typeBuilder.DefineMethod("Show", MethodAttributes.Public, null, new Type[] { typeof(int), typeof(string) });
        FieldBuilder fieldUser = typeBuilder.DefineField("objUser", typeof(User), FieldAttributes.Private | FieldAttributes.Static);

        #region Newobj
        ILGenerator ilOfShow = showMethod.GetILGenerator();      
        //*OpCodes.Stsfld不需要OpCodes.Ldarg_0,this.Name = new User();
        ilOfShow.Emit(OpCodes.Newobj, typeof(User).GetConstructor(new Type[0]));
        ilOfShow.Emit(OpCodes.Stsfld, fieldUser);
        LocalBuilder localName = ilOfShow.DeclareLocal(typeof(string));
        ilOfShow.Emit(OpCodes.Ldstr, "姓名:{1} 年龄:{0}");
        ilOfShow.Emit(OpCodes.Ldc_I4, 18);
        //OpCodes.Ldloc之前不能有OpCodes.Ldarg_0
        ilOfShow.Emit(OpCodes.Ldloc, localName);
        ilOfShow.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(int), typeof(string) }));
        ilOfShow.Emit(OpCodes.Pop);
        ilOfShow.Emit(OpCodes.Ret);
        #endregion

        Type t = typeBuilder.CreateType();
        assemblyBuilder.Save("StudyOpCodes.dll"); 
    }
}    

.Net Reflector转化后的C#代码:

public class StudyOpCodes
{
    // Fields
    private static User objUser;

    // Methods
    public void Show(int, string)
    {
        string str;
        objUser = new User();
        string.Format("姓名:{1} 年龄:{0}", 0x12, str);
    }
}

Newarr

Emit代码:

public class StudyOpCodes
{
    public void Test()
    {
        AssemblyName assemblyName = new AssemblyName("Study");
        AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
        ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("StudyModule", "StudyOpCodes.dll");
        TypeBuilder typeBuilder = moduleBuilder.DefineType("StudyOpCodes", TypeAttributes.Public);
        MethodBuilder showMethod = typeBuilder.DefineMethod("Show", MethodAttributes.Public, null, new Type[] { typeof(int), typeof(string) });
        FieldBuilder fieldArray = typeBuilder.DefineField("objUser", typeof(string[]), FieldAttributes.Private);

        #region 不对数组赋值
        ILGenerator ilOfShow = showMethod.GetILGenerator();
        LocalBuilder localName = ilOfShow.DeclareLocal(typeof(string));        
        //*objUser = new string[3];
        //此处的OpCodes.Ldarg_0是OpCodes.Stfld所需的
        ilOfShow.Emit(OpCodes.Ldarg_0);
        ilOfShow.Emit(OpCodes.Ldc_I4, 3);
        ilOfShow.Emit(OpCodes.Newarr, typeof(string));
        ilOfShow.Emit(OpCodes.Stfld, fieldArray);
        ilOfShow.Emit(OpCodes.Ret);
        #endregion

        #region 对数组赋值
        ILGenerator ilOfShow = showMethod.GetILGenerator();
        LocalBuilder localName = ilOfShow.DeclareLocal(typeof(string));
        //objUser = new string[3];
        //此处的OpCodes.Ldarg_0是OpCodes.Stfld所需的
        ilOfShow.Emit(OpCodes.Ldarg_0);
        ilOfShow.Emit(OpCodes.Ldc_I4, 3);
        ilOfShow.Emit(OpCodes.Newarr, typeof(string));
        ilOfShow.Emit(OpCodes.Stfld, fieldArray);
        //给数组赋值:objUser = new string[] { "aaa", "bbb", "ccc" };
        //此处的OpCodes.Ldarg_0是OpCodes.Ldfld所需的
        ilOfShow.Emit(OpCodes.Ldarg_0);
        ilOfShow.Emit(OpCodes.Ldfld, fieldArray);
        ilOfShow.Emit(OpCodes.Ldc_I4, 0);
        ilOfShow.Emit(OpCodes.Ldstr, "aaa");
        ilOfShow.Emit(OpCodes.Stelem_Ref);
        //此处的OpCodes.Ldarg_0是OpCodes.Ldfld所需的
        ilOfShow.Emit(OpCodes.Ldarg_0);
        ilOfShow.Emit(OpCodes.Ldfld, fieldArray);
        ilOfShow.Emit(OpCodes.Ldc_I4, 1);
        ilOfShow.Emit(OpCodes.Ldstr, "bbb");
        ilOfShow.Emit(OpCodes.Stelem_Ref);
        //此处的OpCodes.Ldarg_0是OpCodes.Ldfld所需的
        ilOfShow.Emit(OpCodes.Ldarg_0);
        ilOfShow.Emit(OpCodes.Ldfld, fieldArray);
        ilOfShow.Emit(OpCodes.Ldc_I4, 2);
        ilOfShow.Emit(OpCodes.Ldstr, "ccc");
        ilOfShow.Emit(OpCodes.Stelem_Ref);
        ilOfShow.Emit(OpCodes.Ret);
        #endregion

        Type t = typeBuilder.CreateType();
        assemblyBuilder.Save("StudyOpCodes.dll");
    }
}    

.Net Reflector转化后的C#代码:

//不对数组赋值
public class StudyOpCodes
{
    // Fields
    private string[] objUser;

    // Methods
    public void Show(int, string)
    {
        this.objUser = new string[3];
    }
}
//对数组赋值
public class StudyOpCodes
{
    // Fields
    private string[] objUser;

    // Methods
    public void Show(int, string)
    {
        objUser = new string[] { "aaa", "bbb", "ccc" };
    }
}

【构造方法】Ldstr和OpCodes.Ldarg_1

Emit代码:

public class StudyOpCodes
{
    public void Test()
    {
        AssemblyName assemblyName = new AssemblyName("Study");
        AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
        ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("StudyModule", "StudyOpCodes.dll");
        TypeBuilder typeBuilder = moduleBuilder.DefineType("StudyOpCodes", TypeAttributes.Public);
        ConstructorBuilder ctorMethod = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[] { typeof(int), typeof(string) });

        ILGenerator ilOfCtor = ctorMethod.GetILGenerator();
        //非静态方法参数索引从1开始
        ilOfCtor.Emit(OpCodes.Ldstr, "姓名:{1} 年龄:{0}");
        ilOfCtor.Emit(OpCodes.Ldarg_1);
        ilOfCtor.Emit(OpCodes.Ldarg_2);
        ilOfCtor.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(int), typeof(string) }));
        ilOfCtor.Emit(OpCodes.Pop);
        ilOfCtor.Emit(OpCodes.Ret);
        Type t = typeBuilder.CreateType();
        assemblyBuilder.Save("StudyOpCodes.dll"); 
    }
}    

.Net Reflector转化后的C#代码:

public class StudyOpCodes
{
    // Methods
    public StudyOpCodes(int num1, string text1)
    {
        string.Format("姓名:{1} 年龄:{0}", num1, text1);
    }
}

总结

除了OpCodes.Ldfld和OpCodes.Stfld命令使用之前需要额外执行OpCodes.Ldarg_0之外,其他命令都不需要。
上面列出了常用的OpCodes指令的使用方法,当然只是一些基本的使用方法,复杂的使用情况(封装、继承、多态等)在此没有举例,不过有了基础再进一步学习复杂功能的写法也会轻松许多,如果遇到问题就上网或使用.Net Reflector和ildasm.exe来解决,希望对大家有帮助。
实例代码免费下载地址:http://download.csdn.net/detail/xiaouncle/9655543

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

changuncle

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值