当前位置: 首页>>代码示例>>C#>>正文


C# TypeBuilder类代码示例

本文整理汇总了C#中System.Reflection.Emit.TypeBuilder的典型用法代码示例。如果您正苦于以下问题:C# TypeBuilder类的具体用法?C# TypeBuilder怎么用?C# TypeBuilder使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。


TypeBuilder类属于System.Reflection.Emit命名空间,在下文中一共展示了TypeBuilder类的2个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。

示例1: Main

//引入命名空间
using System;
using System.Reflection;
using System.Reflection.Emit;

class DemoAssemblyBuilder
{
    public static void Main()
    {
        // An assembly consists of one or more modules, each of which
        // contains zero or more types. This code creates a single-module
        // assembly, the most common case. The module contains one type,
        // named "MyDynamicType", that has a private field, a property 
        // that gets and sets the private field, constructors that 
        // initialize the private field, and a method that multiplies 
        // a user-supplied number by the private field value and returns
        // the result. In C# the type might look like this:
        /*
        public class MyDynamicType
        {
            private int m_number;
        
            public MyDynamicType() : this(42) {}
            public MyDynamicType(int initNumber)
            {
                m_number = initNumber;
            }

            public int Number
            {
                get { return m_number; }
                set { m_number = value; }
            }

            public int MyMethod(int multiplier)
            {
                return m_number * multiplier;
            }
        }
        */
      
        AssemblyName aName = new AssemblyName("DynamicAssemblyExample");
        AssemblyBuilder ab = 
            AppDomain.CurrentDomain.DefineDynamicAssembly(
                aName, 
                AssemblyBuilderAccess.RunAndSave);

        // For a single-module assembly, the module name is usually
        // the assembly name plus an extension.
        ModuleBuilder mb = 
            ab.DefineDynamicModule(aName.Name, aName.Name + ".dll");
      
        TypeBuilder tb = mb.DefineType(
            "MyDynamicType", 
             TypeAttributes.Public);

        // Add a private field of type int (Int32).
        FieldBuilder fbNumber = tb.DefineField(
            "m_number", 
            typeof(int), 
            FieldAttributes.Private);

        // Define a constructor that takes an integer argument and 
        // stores it in the private field. 
        Type[] parameterTypes = { typeof(int) };
        ConstructorBuilder ctor1 = tb.DefineConstructor(
            MethodAttributes.Public, 
            CallingConventions.Standard, 
            parameterTypes);

        ILGenerator ctor1IL = ctor1.GetILGenerator();
        // For a constructor, argument zero is a reference to the new
        // instance. Push it on the stack before calling the base
        // class constructor. Specify the default constructor of the 
        // base class (System.Object) by passing an empty array of 
        // types (Type.EmptyTypes) to GetConstructor.
        ctor1IL.Emit(OpCodes.Ldarg_0);
        ctor1IL.Emit(OpCodes.Call, 
            typeof(object).GetConstructor(Type.EmptyTypes));
        // Push the instance on the stack before pushing the argument
        // that is to be assigned to the private field m_number.
        ctor1IL.Emit(OpCodes.Ldarg_0);
        ctor1IL.Emit(OpCodes.Ldarg_1);
        ctor1IL.Emit(OpCodes.Stfld, fbNumber);
        ctor1IL.Emit(OpCodes.Ret);

        // Define a default constructor that supplies a default value
        // for the private field. For parameter types, pass the empty
        // array of types or pass null.
        ConstructorBuilder ctor0 = tb.DefineConstructor(
            MethodAttributes.Public, 
            CallingConventions.Standard, 
            Type.EmptyTypes);

        ILGenerator ctor0IL = ctor0.GetILGenerator();
        // For a constructor, argument zero is a reference to the new
        // instance. Push it on the stack before pushing the default
        // value on the stack, then call constructor ctor1.
        ctor0IL.Emit(OpCodes.Ldarg_0);
        ctor0IL.Emit(OpCodes.Ldc_I4_S, 42);
        ctor0IL.Emit(OpCodes.Call, ctor1);
        ctor0IL.Emit(OpCodes.Ret);

        // Define a property named Number that gets and sets the private 
        // field.
        //
        // The last argument of DefineProperty is null, because the
        // property has no parameters. (If you don't specify null, you must
        // specify an array of Type objects. For a parameterless property,
        // use the built-in array with no elements: Type.EmptyTypes)
        PropertyBuilder pbNumber = tb.DefineProperty(
            "Number", 
            PropertyAttributes.HasDefault, 
            typeof(int), 
            null);
      
        // The property "set" and property "get" methods require a special
        // set of attributes.
        MethodAttributes getSetAttr = MethodAttributes.Public | 
            MethodAttributes.SpecialName | MethodAttributes.HideBySig;

        // Define the "get" accessor method for Number. The method returns
        // an integer and has no arguments. (Note that null could be 
        // used instead of Types.EmptyTypes)
        MethodBuilder mbNumberGetAccessor = tb.DefineMethod(
            "get_Number", 
            getSetAttr, 
            typeof(int), 
            Type.EmptyTypes);
      
        ILGenerator numberGetIL = mbNumberGetAccessor.GetILGenerator();
        // For an instance property, argument zero is the instance. Load the 
        // instance, then load the private field and return, leaving the
        // field value on the stack.
        numberGetIL.Emit(OpCodes.Ldarg_0);
        numberGetIL.Emit(OpCodes.Ldfld, fbNumber);
        numberGetIL.Emit(OpCodes.Ret);
        
        // Define the "set" accessor method for Number, which has no return
        // type and takes one argument of type int (Int32).
        MethodBuilder mbNumberSetAccessor = tb.DefineMethod(
            "set_Number", 
            getSetAttr, 
            null, 
            new Type[] { typeof(int) });
      
        ILGenerator numberSetIL = mbNumberSetAccessor.GetILGenerator();
        // Load the instance and then the numeric argument, then store the
        // argument in the field.
        numberSetIL.Emit(OpCodes.Ldarg_0);
        numberSetIL.Emit(OpCodes.Ldarg_1);
        numberSetIL.Emit(OpCodes.Stfld, fbNumber);
        numberSetIL.Emit(OpCodes.Ret);
      
        // Last, map the "get" and "set" accessor methods to the 
        // PropertyBuilder. The property is now complete. 
        pbNumber.SetGetMethod(mbNumberGetAccessor);
        pbNumber.SetSetMethod(mbNumberSetAccessor);

        // Define a method that accepts an integer argument and returns
        // the product of that integer and the private field m_number. This
        // time, the array of parameter types is created on the fly.
        MethodBuilder meth = tb.DefineMethod(
            "MyMethod", 
            MethodAttributes.Public, 
            typeof(int), 
            new Type[] { typeof(int) });

        ILGenerator methIL = meth.GetILGenerator();
        // To retrieve the private instance field, load the instance it
        // belongs to (argument zero). After loading the field, load the 
        // argument one and then multiply. Return from the method with 
        // the return value (the product of the two numbers) on the 
        // execution stack.
        methIL.Emit(OpCodes.Ldarg_0);
        methIL.Emit(OpCodes.Ldfld, fbNumber);
        methIL.Emit(OpCodes.Ldarg_1);
        methIL.Emit(OpCodes.Mul);
        methIL.Emit(OpCodes.Ret);

        // Finish the type.
        Type t = tb.CreateType();
     
        // The following line saves the single-module assembly. This
        // requires AssemblyBuilderAccess to include Save. You can now
        // type "ildasm MyDynamicAsm.dll" at the command prompt, and 
        // examine the assembly. You can also write a program that has
        // a reference to the assembly, and use the MyDynamicType type.
        // 
        ab.Save(aName.Name + ".dll");

        // Because AssemblyBuilderAccess includes Run, the code can be
        // executed immediately. Start by getting reflection objects for
        // the method and the property.
        MethodInfo mi = t.GetMethod("MyMethod");
        PropertyInfo pi = t.GetProperty("Number");
  
        // Create an instance of MyDynamicType using the default 
        // constructor. 
        object o1 = Activator.CreateInstance(t);

        // Display the value of the property, then change it to 127 and 
        // display it again. Use null to indicate that the property
        // has no index.
        Console.WriteLine("o1.Number: {0}", pi.GetValue(o1, null));
        pi.SetValue(o1, 127, null);
        Console.WriteLine("o1.Number: {0}", pi.GetValue(o1, null));

        // Call MyMethod, passing 22, and display the return value, 22
        // times 127. Arguments must be passed as an array, even when
        // there is only one.
        object[] arguments = { 22 };
        Console.WriteLine("o1.MyMethod(22): {0}", 
            mi.Invoke(o1, arguments));

        // Create an instance of MyDynamicType using the constructor
        // that specifies m_Number. The constructor is identified by
        // matching the types in the argument array. In this case, 
        // the argument array is created on the fly. Display the 
        // property value.
        object o2 = Activator.CreateInstance(t, 
            new object[] { 5280 });
        Console.WriteLine("o2.Number: {0}", pi.GetValue(o2, null));
    }
}
开发者ID:.NET开发者,项目名称:System.Reflection.Emit,代码行数:225,代码来源:TypeBuilder

输出:

o1.Number: 42
o1.Number: 127
o1.MyMethod(22): 2794
o2.Number: 5280

示例2: DynamicDotProductGen

//引入命名空间
using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;

class TestILGenerator {
 
    public static Type DynamicDotProductGen() {
      
       Type ivType = null;
       Type[] ctorParams = new Type[] { typeof(int),
                                typeof(int),
                        typeof(int)};
    
       AppDomain myDomain = Thread.GetDomain();
       AssemblyName myAsmName = new AssemblyName();
       myAsmName.Name = "IntVectorAsm";
    
       AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(
                      myAsmName, 
                      AssemblyBuilderAccess.RunAndSave);

       ModuleBuilder IntVectorModule = myAsmBuilder.DefineDynamicModule("IntVectorModule",
                                        "Vector.dll");

       TypeBuilder ivTypeBld = IntVectorModule.DefineType("IntVector",
                                      TypeAttributes.Public);

       FieldBuilder xField = ivTypeBld.DefineField("x", typeof(int),
                                                       FieldAttributes.Private);
       FieldBuilder yField = ivTypeBld.DefineField("y", typeof(int), 
                                                       FieldAttributes.Private);
       FieldBuilder zField = ivTypeBld.DefineField("z", typeof(int),
                                                       FieldAttributes.Private);

           Type objType = Type.GetType("System.Object"); 
           ConstructorInfo objCtor = objType.GetConstructor(new Type[0]);

       ConstructorBuilder ivCtor = ivTypeBld.DefineConstructor(
                      MethodAttributes.Public,
                      CallingConventions.Standard,
                      ctorParams);
       ILGenerator ctorIL = ivCtor.GetILGenerator();
           ctorIL.Emit(OpCodes.Ldarg_0);
           ctorIL.Emit(OpCodes.Call, objCtor);
           ctorIL.Emit(OpCodes.Ldarg_0);
           ctorIL.Emit(OpCodes.Ldarg_1);
           ctorIL.Emit(OpCodes.Stfld, xField); 
           ctorIL.Emit(OpCodes.Ldarg_0);
           ctorIL.Emit(OpCodes.Ldarg_2);
           ctorIL.Emit(OpCodes.Stfld, yField); 
           ctorIL.Emit(OpCodes.Ldarg_0);
           ctorIL.Emit(OpCodes.Ldarg_3);
           ctorIL.Emit(OpCodes.Stfld, zField); 
       ctorIL.Emit(OpCodes.Ret); 

       // This method will find the dot product of the stored vector
       // with another.

       Type[] dpParams = new Type[] { ivTypeBld };

           // Here, you create a MethodBuilder containing the
       // name, the attributes (public, static, private, and so on),
       // the return type (int, in this case), and a array of Type
       // indicating the type of each parameter. Since the sole parameter
       // is a IntVector, the very class you're creating, you will
       // pass in the TypeBuilder (which is derived from Type) instead of 
       // a Type object for IntVector, avoiding an exception. 

       // -- This method would be declared in C# as:
       //    public int DotProduct(IntVector aVector)

           MethodBuilder dotProductMthd = ivTypeBld.DefineMethod(
                                  "DotProduct", 
                          MethodAttributes.Public,
                                          typeof(int), 
                                          dpParams);

       // A ILGenerator can now be spawned, attached to the MethodBuilder.

       ILGenerator mthdIL = dotProductMthd.GetILGenerator();
       
       // Here's the body of our function, in MSIL form. We're going to find the
       // "dot product" of the current vector instance with the passed vector 
       // instance. For reference purposes, the equation is:
       // (x1 * x2) + (y1 * y2) + (z1 * z2) = the dot product

       // First, you'll load the reference to the current instance "this"
       // stored in argument 0 (ldarg.0) onto the stack. Ldfld, the subsequent
       // instruction, will pop the reference off the stack and look up the
       // field "x", specified by the FieldInfo token "xField".

       mthdIL.Emit(OpCodes.Ldarg_0);
       mthdIL.Emit(OpCodes.Ldfld, xField);

       // That completed, the value stored at field "x" is now atop the stack.
       // Now, you'll do the same for the object reference we passed as a
       // parameter, stored in argument 1 (ldarg.1). After Ldfld executed,
       // you'll have the value stored in field "x" for the passed instance
       // atop the stack.

       mthdIL.Emit(OpCodes.Ldarg_1);
       mthdIL.Emit(OpCodes.Ldfld, xField);

           // There will now be two values atop the stack - the "x" value for the
       // current vector instance, and the "x" value for the passed instance.
       // You'll now multiply them, and push the result onto the evaluation stack.

       mthdIL.Emit(OpCodes.Mul_Ovf_Un);

       // Now, repeat this for the "y" fields of both vectors.

       mthdIL.Emit(OpCodes.Ldarg_0);
       mthdIL.Emit(OpCodes.Ldfld, yField);
       mthdIL.Emit(OpCodes.Ldarg_1);
       mthdIL.Emit(OpCodes.Ldfld, yField);
       mthdIL.Emit(OpCodes.Mul_Ovf_Un);

       // At this time, the results of both multiplications should be atop
       // the stack. You'll now add them and push the result onto the stack.

       mthdIL.Emit(OpCodes.Add_Ovf_Un);

       // Multiply both "z" field and push the result onto the stack.
       mthdIL.Emit(OpCodes.Ldarg_0);
       mthdIL.Emit(OpCodes.Ldfld, zField);
       mthdIL.Emit(OpCodes.Ldarg_1);
       mthdIL.Emit(OpCodes.Ldfld, zField);
       mthdIL.Emit(OpCodes.Mul_Ovf_Un);

       // Finally, add the result of multiplying the "z" fields with the
       // result of the earlier addition, and push the result - the dot product -
       // onto the stack.
       mthdIL.Emit(OpCodes.Add_Ovf_Un);

       // The "ret" opcode will pop the last value from the stack and return it
       // to the calling method. You're all done!

       mthdIL.Emit(OpCodes.Ret);

       ivType = ivTypeBld.CreateType();

       return ivType;
    }

    public static void Main() {
    
       Type IVType = null;
           object aVector1 = null;
           object aVector2 = null;
       Type[] aVtypes = new Type[] {typeof(int), typeof(int), typeof(int)};
           object[] aVargs1 = new object[] {10, 10, 10};
           object[] aVargs2 = new object[] {20, 20, 20};
    
       // Call the  method to build our dynamic class.

       IVType = DynamicDotProductGen();

           Console.WriteLine("---");

       ConstructorInfo myDTctor = IVType.GetConstructor(aVtypes);
       aVector1 = myDTctor.Invoke(aVargs1);
       aVector2 = myDTctor.Invoke(aVargs2);

       object[] passMe = new object[1];
           passMe[0] = (object)aVector2; 

       Console.WriteLine("(10, 10, 10) . (20, 20, 20) = {0}",
                 IVType.InvokeMember("DotProduct",
                          BindingFlags.InvokeMethod,
                          null,
                          aVector1,
                          passMe));

       // +++ OUTPUT +++
       // ---
       // (10, 10, 10) . (20, 20, 20) = 600 
    }
}
开发者ID:.NET开发者,项目名称:System.Reflection.Emit,代码行数:180,代码来源:TypeBuilder


注:本文中的System.Reflection.Emit.TypeBuilder类示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。