| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- using System;
- using System.Reflection;
- using System.Reflection.Emit;
-
- namespace EmitCreateMembers
- {
- class Program
- {
- static void Main(string[] args)
- {
- // specify a new assembly name
- var assemblyName = new AssemblyName("Pets");
-
- // create assembly builder
- var assemblyBuilder = AppDomain.CurrentDomain
- .DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
-
- // create module builder
- var moduleBuilder = assemblyBuilder.DefineDynamicModule("PetsModule", "Pets.dll");
-
- // create type builder for a class
- var typeBuilder = moduleBuilder.DefineType("Kitty", TypeAttributes.Public);
-
- // then create whole class structure
- CreateKittyClassStructure(typeBuilder);
-
- // then create the whole class type
- var classType = typeBuilder.CreateType();
-
- // save assembly
- assemblyBuilder.Save("Pets.dll");
-
- Console.WriteLine("Hi, Dennis, a Pets assembly has been generated for you.");
- Console.ReadLine();
- }
-
- private static void CreateKittyClassStructure(TypeBuilder typeBuilder)
- {
- // ---- define fields ----
-
- var fieldId = 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) };
-
- var constructorBuilder = typeBuilder.DefineConstructor(
- MethodAttributes.Public, CallingConventions.Standard, constructorArgs);
- ILGenerator ilOfCtor = constructorBuilder.GetILGenerator();
-
- 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);
- ilOfCtor.Emit(OpCodes.Ret);
-
- // ---- define properties ----
-
- var methodGetId = typeBuilder.DefineMethod(
- "GetId", MethodAttributes.Public, typeof(int), null);
- var methodSetId = typeBuilder.DefineMethod(
- "SetId", MethodAttributes.Public, null, new Type[] { typeof(int) });
-
- var ilOfGetId = methodGetId.GetILGenerator();
- ilOfGetId.Emit(OpCodes.Ldarg_0); // this
- ilOfGetId.Emit(OpCodes.Ldfld, fieldId);
- ilOfGetId.Emit(OpCodes.Ret);
-
- var ilOfSetId = methodSetId.GetILGenerator();
- ilOfSetId.Emit(OpCodes.Ldarg_0); // this
- ilOfSetId.Emit(OpCodes.Ldarg_1); // the first one in arguments list
- ilOfSetId.Emit(OpCodes.Stfld, fieldId);
- ilOfSetId.Emit(OpCodes.Ret);
-
- // create Id property
- var propertyId = typeBuilder.DefineProperty(
- "Id", PropertyAttributes.None, typeof(int), null);
- propertyId.SetGetMethod(methodGetId);
- propertyId.SetSetMethod(methodSetId);
-
- var methodGetName = typeBuilder.DefineMethod(
- "GetName", MethodAttributes.Public, typeof(string), null);
- var methodSetName = typeBuilder.DefineMethod(
- "SetName", MethodAttributes.Public, null, new Type[] { typeof(string) });
-
- var ilOfGetName = methodGetName.GetILGenerator();
- ilOfGetName.Emit(OpCodes.Ldarg_0); // this
- ilOfGetName.Emit(OpCodes.Ldfld, fieldName);
- ilOfGetName.Emit(OpCodes.Ret);
-
- var ilOfSetName = methodSetName.GetILGenerator();
- ilOfSetName.Emit(OpCodes.Ldarg_0); // this
- ilOfSetName.Emit(OpCodes.Ldarg_1); // the first one in arguments list
- ilOfSetName.Emit(OpCodes.Stfld, fieldName);
- ilOfSetName.Emit(OpCodes.Ret);
-
- // create Name property
- var propertyName = typeBuilder.DefineProperty(
- "Name", PropertyAttributes.None, typeof(string), null);
- propertyName.SetGetMethod(methodGetName);
- propertyName.SetSetMethod(methodSetName);
-
- // ---- define methods ----
-
- // create ToString() method
- var methodToString = typeBuilder.DefineMethod(
- "ToString",
- MethodAttributes.Virtual | MethodAttributes.Public,
- typeof(string),
- null);
-
- var ilOfToString = methodToString.GetILGenerator();
- var local = ilOfToString.DeclareLocal(typeof(string)); // create a local variable
- ilOfToString.Emit(OpCodes.Ldstr, "Id:[{0}], Name:[{1}]");
- ilOfToString.Emit(OpCodes.Ldarg_0); // this
- ilOfToString.Emit(OpCodes.Ldfld, fieldId);
- ilOfToString.Emit(OpCodes.Box, typeof(int)); // boxing the value type to object
- ilOfToString.Emit(OpCodes.Ldarg_0); // this
- ilOfToString.Emit(OpCodes.Ldfld, fieldName);
- ilOfToString.Emit(OpCodes.Call,
- typeof(string).GetMethod("Format",
- new Type[] { typeof(string), typeof(object), typeof(object) }));
- ilOfToString.Emit(OpCodes.Stloc, local); // set local variable
- ilOfToString.Emit(OpCodes.Ldloc, local); // load local variable to stack
- ilOfToString.Emit(OpCodes.Ret);
- }
- }
- }
|