zoukankan      html  css  js  c++  java
  • MSIL实用指南-创建方法和定义参数

     本篇讲解实现创建方法、指定参数的名称、实现参数加out和ref修饰符、以及参数加默认值。

    创建方法

    创建方法用类TypeAttributes的

    DefineMethod(string name, MethodAttributes attributes, Type returnType, Type[] parameterTypes)

    方法,返回结果是MethodBuilder,就可以创普通方法。

    例子

    MethodBuilder m2 = typeBuilder.DefineMethod("M2",
    MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual,
    typeof(string), new Type[] { typeof(int), typeof(string), typeof(object) });

    这个写法就和下面的C#程序一样

    public abstract void M1();

    定义一个抽象方法需要用MethodAttributes的Abstract|Virtual才可以。

    定义参数

    用MethodBuilder的DefineParameter(int position, ParameterAttributes attributes, string strParamName)

    方法

     参数说明

    position:该参数在参数列表中的位置。为参数编索引,第一个参数从数字 1 开始;数字 0 表示方法的返回值。

    attributes: 参数的参数属性。

    strParamName: 参数名。名称可以为 null 字符串。

    返回结果:

    返回一个 ParameterBuilder 对象,该对象表示此方法的参数或此方法的返回值。

    1.指定参数的名称

    在程序的方法调用中传入第三个参数传入参数名称就可以了。

    例如

    MethodBuilder m2 = typeBuilder.DefineMethod("M2",
                   MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual,
                   typeof(string), new Type[] { typeof(int), typeof(string), typeof(object) });
    
    m2.DefineParameter(1, ParameterAttributes.None, "arg0");
    m2.DefineParameter(2, ParameterAttributes.None, "param1");
    m2.DefineParameter(3, ParameterAttributes.None, "param2");

    这个方法的三个参数名称依次是arg0、param1、param2。

    2.指定参数out

    我们要实现如下方法,参数的修饰符是out

    public abstract string mout(out int arg3 );

    需要使用ParameterAttributes.Out就可以了。

    具体实现

    MethodBuilder m5 = typeBuilder.DefineMethod("mout",
                   MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual,
                   typeof(string), new Type[] { typeof(int), typeof(int) });
    
                ParameterBuilder m5p1 = m5.DefineParameter(1, ParameterAttributes.Out, "arg3");
    

    3.实现参数默认值

    要实现参数有默认值,比如下面这句

    public abstract string mdefault(int arg1 =4 );

    实现这个效果的程序是

    MethodBuilder m3 = typeBuilder.DefineMethod("mdefault",
                   MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual,
                   typeof(string), new Type[] { typeof(int) });
    
                ParameterBuilder m3p1 = m3.DefineParameter(1, ParameterAttributes.HasDefault | ParameterAttributes.Optional, "arg1");
                m3p1.SetConstant(4);

    实现定义参数属性为ParameterAttributes.HasDefault | ParameterAttributes.Optional,并得到一个

    ParameterBuilder实例,再设置这个实例的默认值。

    4.实现指定参数ref

    我们要实现如下方法,参数的修饰符是out

    public abstract string mref(ref dobule arg2);

    首先

    MethodBuilder m4 = typeBuilder.DefineMethod("mref",
                   MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual,
                   typeof(string), new Type[] { Type.GetType("System.Double&") });

    参数的类型不是一般的typeof(double),而要用特殊的Type.GetType("System.Double&")

    其次

    ParameterBuilder m4p1 = m4.DefineParameter(1, ParameterAttributes.Out, "arg2");

    要设置参数的属性为ParameterAttributes.Out

    完整程序如下

    using System;
    using System.Reflection;
    using System.Reflection.Emit;
    
    namespace LX1_ILDemo
    {
        class Demo07_Method
        {
            static string binaryName = "Demo07_Method.dll";
            static string namespaceName = "LX1_ILDemo";
            static string typeName = "EmitMethod";
    
            static AssemblyBuilder assemblyBuilder;
            static ModuleBuilder moduleBuilder;
            static TypeBuilder typeBuilder;
    
            public static void Generate()
            {
                InitAssembly();
    
                typeBuilder = moduleBuilder.DefineType(namespaceName + "." + typeName,
                    TypeAttributes.Public | TypeAttributes.Abstract);
    
                /* 生成 public static void Main() */
                GenerateMethods();
    
                SaveAssembly();
                Console.WriteLine("生成成功");
            }
    
            static void GenerateMethods()
            {
                /* public abstract void M1(); */
                MethodBuilder m1 = typeBuilder.DefineMethod("M1",
                    MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual,
                    typeof(void), new Type[] { });
    
                /* public abstract string M2(int arg0,string param1); */
                MethodBuilder m2 = typeBuilder.DefineMethod("M2",
                   MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual,
                   typeof(string), new Type[] { typeof(int), typeof(string), typeof(object) });
    
                m2.DefineParameter(1, ParameterAttributes.None, "arg0");
                m2.DefineParameter(2, ParameterAttributes.None, "param1");
                m2.DefineParameter(3, ParameterAttributes.None, "param2");
    
                /* public abstract string mdefault(int arg1 =4 ); */
                MethodBuilder m3 = typeBuilder.DefineMethod("mdefault",
                   MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual,
                   typeof(string), new Type[] { typeof(int) });
    
                ParameterBuilder m3p1 = m3.DefineParameter(1, ParameterAttributes.HasDefault | ParameterAttributes.Optional, "arg1");
                m3p1.SetConstant(4);
    
                /* public abstract string mref(ref dobule arg2); */
                MethodBuilder m4 = typeBuilder.DefineMethod("mref",
                   MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual,
                   typeof(string), new Type[] { Type.GetType("System.Double&") });
    
                ParameterBuilder m4p1 = m4.DefineParameter(1, ParameterAttributes.Out, "arg2");
    
    
                /* public abstract string mout(out int arg3 ); */
                MethodBuilder m5 = typeBuilder.DefineMethod("mout",
                   MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual,
                   typeof(string), new Type[] { typeof(int), typeof(int) });
    
                ParameterBuilder m5p1 = m5.DefineParameter(1, ParameterAttributes.Out, "arg3");
            }
    
    
            static void InitAssembly()
            {
                AssemblyName assemblyName = new AssemblyName(namespaceName);
                assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
                moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name, binaryName);
            }
    
            static void SaveAssembly()
            {
                Type t = typeBuilder.CreateType(); //完成Type,这是必须的
                assemblyBuilder.Save(binaryName);
            }
        }
    }
    View Code
  • 相关阅读:
    ASP.NET编程的十大技巧
    C#学习心得(转)
    POJ 1177 Picture (线段树)
    POJ 3067 Japan (树状数组)
    POJ 2828 Buy Tickets (线段树)
    POJ 1195 Mobile phones (二维树状数组)
    HDU 4235 Flowers (线段树)
    POJ 2886 Who Gets the Most Candies? (线段树)
    POJ 2418 Cows (树状数组)
    HDU 4339 Query (线段树)
  • 原文地址:https://www.cnblogs.com/tkt2016/p/8617438.html
Copyright © 2011-2022 走看看