C # uses emit to build constructors and properties

Source: Internet
Author: User
Tags emit

Suppose we need a class named Kitty, which is under the Pets assembly.

1     //Specify a new assembly name 2     var assemblyname = new AssemblyName ("Pets"); 3  4     //CREATE Assembly Bui Lder 5     var assemblybuilder = Appdomain.currentdomain 6       . DefineDynamicAssembly (AssemblyName, Assemblybuilderaccess.runandsave); 7  8     //Create Module Builder 9     var modulebuilder = assemblybuilder.definedynamicmodule ("Petsmodule", " Pets.dll ")     //Create Type builder for a class12     var typeBuilder = Modulebuilder.definetype (" Kitty ", TypeA Ttributes. public);
Defining fields

The Kitty class consists of two private fields _id and _name. Defined with a type constructor,

1     var fieldid = Typebuilder.definefield (2       "_id", typeof (int), fieldattributes.private); 3     var fieldName = Typebuilder.definefield (4       "_name", typeof (String), fieldattributes.private);
Defining constructors

The Kitty class contains a constructor with two parameters, one for the integer ID, and the string name for the parameter. constructor, assign the parameter ID to the private field _id, assign the parameter name to the private field _name,

1     Type objType = Type.GetType ("System.Object"); 2     ConstructorInfo objctor = objtype.getconstructor (new type[0] ); 3  4     type[] Constructorargs = {typeof (int), typeof (String)}; 5  6     var constructorbuilder = Typebuilder.defineconstructor (7         methodattributes.public, Callingconventions.standard, ConstructorArgs); 8     ILGenerator ilofctor = Constructorbuilder.getilgenerator (); 9     ilofctor.emit (OPCODES.LDARG_0);     Ilofctor.emit (Opcodes.call, objctor);     ilofctor.emit (OPCODES.LDARG_0);     Ilofctor.emit (Opcodes.ldarg _1),     ilofctor.emit (OPCODES.STFLD, FieldID), Ilofctor.emit (     opcodes.ldarg_0), Ilofctor.emit     ( opcodes.ldarg_2);     ilofctor.emit (OPCODES.STFLD, fieldName); 18     
Defining properties

Create ID and name two properties for the Kitty class, read and set private fields _id and _name. The properties in C # define getter and setter two methods respectively.

 1 var methodgetid = Typebuilder.definemethod (2 "GetId", Methodattributes.public, typeof (int), NULL);  3 var Methodsetid = Typebuilder.definemethod (4 "SetId", methodattributes.public, NULL, new type[] {typeof (int) }); 5 6 var Ilofgetid = Methodgetid.getilgenerator (); 7 Ilofgetid.emit (OPCODES.LDARG_0); This 8 ilofgetid.emit (OPCODES.LDFLD, FieldID); 9 Ilofgetid.emit (Opcodes.ret); var ilofsetid = Methodsetid.getilgenerator (); Ilofsetid.emit (Opcodes.lda RG_0); This13 Ilofsetid.emit (opcodes.ldarg_1);     The first one in arguments list14 ilofsetid.emit (OPCODES.STFLD, FieldID); Ilofsetid.emit (Opcodes.ret); 16 17 Create ID property18 var PropertyId = Typebuilder.defineproperty ("Id", Propertyattributes.none, typeof ( int), NULL); Propertyid.setgetmethod (Methodgetid); Propertyid.setsetmethod (Methodsetid); var Methodge Tname = Typebuilder.definemethod ("GetName", MethodAttributes.Public, typeof (String), null), var methodsetname = Typebuilder.definemethod ("SetName", methodattributes.pub LIC, NULL, new type[] {typeof (String)}); var ilofgetname = Methodgetname.getilgenerator (); Ilofgetname.em It (OPCODES.LDARG_0); This30 Ilofgetname.emit (OPCODES.LDFLD, fieldName); Ilofgetname.emit (Opcodes.ret); + var ilofsetname = Methodsetname.getilgenerator (); Ilofsetname.emit (OPCODES.LDARG_0); This35 Ilofsetname.emit (opcodes.ldarg_1); The first one in arguments list36 ilofsetname.emit (OPCODES.STFLD, fieldName); Panax Notoginseng Ilofsetname.emit (Opcodes.ret); 3 8//Create Name property40 var propertyname = Typebuilder.defineproperty ("name", PROPERTYATTRIBUTES.N One, typeof (String), null); Propertyname.setgetmethod (methodgetname); Propertyname.setsetmethod (Methodsetname) ;
Defining methods

Adds a ToString () method to the Kitty class, returning a string value.

 1//Create ToString () Method 2 var methodtostring = Typebuilder.definemethod (3 "ToString", 4 method attributes.virtual | Methodattributes.public, 5 typeof (String), 6 null); 7 8 var iloftostring = Methodtostring.getilgenerator (); 9 var local = iloftostring.declarelocal (typeof (String)); Create a local Variable10 iloftostring.emit (Opcodes.ldstr, "id:[{0}], name:[{1}]"); Iloftostring.emit (opcodes . LDARG_0); THIS12 Iloftostring.emit (OPCODES.LDFLD, FieldID); Iloftostring.emit (Opcodes.box, typeof (int)); Boxing the value type to object14 iloftostring.emit (OPCODES.LDARG_0); This15 Iloftostring.emit (OPCODES.LDFLD, fieldName); Iloftostring.emit (opcodes.call,17 typeof (String). GetMethod ("Format", new type[] {typeof (String), typeof (Object), typeof (Object)}), Iloftostring.emit (opcod Es. Stloc, local); Set local Variable20 iloftostring.emit (opcodes.ldloc, local); Load local variable to stack21 iloftostring.emit (opcodes.ret); 
Save Type

Build the type and save the assembly to the Pets.dll file.

1     /Then create the whole class type2     var ClassType = TypeBuilder.CreateType (); 3 4     //save Assembly5     Asse Mblybuilder.save ("Pets.dll");
Anti-compilation class

Use the anti-compiler to view the generated classes,

1 using System; 2 public class Kitty 3 {4   private int _id; 5   private string _name; 6 public   int ID 7   {8     get 9     {Ten       return this._id;11     }12     set13     {       this._id = value;15}16   }17   Public String Name18   {     get20     {       this._name;22     }23     set24     {       this._ Name = value;26     }27   }28 public   Kitty (int ID, string name)   {     this._id = id;31     this._ Name = name;32   }33 public   override string ToString ()   . {A     return string. Format ("id:[{0}], name:[{1}]", this._id, This._name);   }37}
Full code
  1 using System;  2 using System.Reflection;  3 using System.Reflection.Emit;       4 5 Namespace Emitcreatemembers 6 {7 Class program 8 {9 static void Main (string[] args) 10 {11 Specify a new assembly name of var assemblyname = new AssemblyName ("Pets"); //CREATE Assembly builder for var AssemblyBuilder = Appdomain.currentdomain 16. DefineDynamicAssembly (AssemblyName, Assemblybuilderaccess.runandsave); +//Create module builder var ModuleBuilder = AssemblyBuilder.DefineDynamicModule ("Petsmodule", "Pets . dll "); //Create Type Builder for a class of var typeBuilder = Modulebuilder.definetype ("Kitty", Typeattribute S.public); */Then create whole class structure createkittyclassstructure (TypeBuilder); +/Then create the whole class type-var ClassType = TypeBuilder.CreateType (); +//Save assembly to Assemblybuilder.save ("Pets.dll");Console.WriteLine ("Hi, Dennis, a Pets assembly have been generated for you."); Console.ReadLine (); Createkittyclassstructure (TypeBuilder TypeBuilder) ($//----Defin  E fields----FieldID var = typebuilder.definefield ("_id", typeof (int), fieldattributes.private); var fieldName = Typebuilder.definefield ("_name", typeof (String), fieldattributes.private); Define//----costructors-----Type ObjType = Type.GetType ("System.Object"); ConstructorInfo objctor = Objtype.getconstructor (new type[0]); Type[] Constructorargs = {typeof (int), typeof (String)}; ConstructorBuilder var = typebuilder.defineconstructor (Methodattributes.public, Callingconventio Ns. Standard, Constructorargs); ILGenerator ilofctor = Constructorbuilder.getilgenerator (); Ilofctor.emit (OPCODES.LDARG_0);       58Ilofctor.emit (Opcodes.call, objctor); Ilofctor.emit (OPCODES.LDARG_0); Ilofctor.emit (opcodes.ldarg_1); Ilofctor.emit (OPCODES.STFLD, FieldID); Ilofctor.emit (OPCODES.LDARG_0); Ilofctor.emit (opcodes.ldarg_2); Ilofctor.emit (OPCODES.STFLD, fieldName); Ilofctor.emit (Opcodes.ret); //----Define properties----Methodgetid = Typebuilder.definemethod ("GetId", M Ethodattributes.public, typeof (int), NULL); Methodsetid var = typebuilder.definemethod ("SetId", methodattributes.public, NULL, new type[] {TYPEO f (int)}); The Ilofgetid var = methodgetid.getilgenerator (); Ilofgetid.emit (OPCODES.LDARG_0); This ilofgetid.emit (OPCODES.LDFLD, FieldID); Ilofgetid.emit (Opcodes.ret); Ilofsetid var = methodsetid.getilgenerator (); Ilofsetid.emit (OPCODES.LDARG_0); This is Bayi ilofsetid.emit (opcodes.ldarg_1); The first oneIn arguments list Ilofsetid.emit (OPCODES.STFLD, FieldID); Ilofsetid.emit (Opcodes.ret); //Create ID Property--var PropertyId = Typebuilder.defineproperty ("id", propertyattribut Es. None, typeof (int), NULL); Propertyid.setgetmethod (Methodgetid); Propertyid.setsetmethod (Methodsetid); methodgetname var = typebuilder.definemethod ("GetName", Methodattributes.public, typeof (String), NULL); methodsetname var = typebuilder.definemethod (94 "SetName", methodattributes.public, NULL, new type[] {T Ypeof (String)}); ilofgetname var = methodgetname.getilgenerator (); Ilofgetname.emit (OPCODES.LDARG_0); This 98 ilofgetname.emit (OPCODES.LDFLD, fieldName); Ilofgetname.emit (Opcodes.ret), 101 var ilofsetname = Methodsetname.getilgenerator (); 102 Ilofsetnam E.emit (OPCODES.LDARG_0); this103 Ilofsetname.emit (opcodes.ldarg_1); The First ONE in Arguments list104 ilofsetname.emit (OPCODES.STFLD, fieldName); Ilofsetname.emit (Opcodes.ret); 106 107 Create Name property108 var propertyname = Typebuilder.defineproperty (109 "Name", PropertyAttributes . None, typeof (String), null); Propertyname.setgetmethod (methodgetname); 111 Propertyname.setsetmethod (MethodS Etname) 113//----Define methods----//Create ToString () method116 var methodtostring = t Ypebuilder.definemethod (117 "ToString", 118 methodattributes.virtual | methodattributes.public,119 typeof (String), (null), 121 122 var iloftostring = Methodtostring.getil Generator (); 123 var local = Iloftostring.declarelocal (typeof (String)); Create a local variable124 iloftostring.emit (Opcodes.ldstr, "id:[{0}], name:[{1}]"), Iloftostring.emit (O PCODES.LDARG_0); this126 Iloftostring.emit (OPCODES.LDFLD, FieldID); 127 Iloftostring.emit (Opcodes.box, typeof (int)); Boxing the value type to object128 iloftostring.emit (OPCODES.LDARG_0); this129 Iloftostring.emit (OPCODES.LDFLD, FieldName), (Iloftostring.emit opcodes.call,131 (s Tring). GetMethod ("Format", new type[] {typeof (String), typeof (Object), typeof (Object)}); 133 Iloftostring.emit (Opcodes.stloc, local); Set local variable134 iloftostring.emit (opcodes.ldloc, local); Load local variable to stack135 iloftostring.emit (Opcodes.ret); 136}137}138}

Download the full code

Learn more about using emit to construct dynamic proxy classes

C # uses emit to build constructors and properties

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.