[转发]C#动态创建和动态使用程序集、类、方法、字段等(二)

作者在 2012-10-12 16:01:33 发布以下内容

一节讲了如何动态的创建,这一节就要讲创建了我们需要如何使用了,这当然也是非常重要的, 是吧。创建了动态类型但是又不使用,那创建它有什么用了。呵呵,今天我们就来一起学习动态使用动态创建的类型。

当然我们跟上一章一样要对这些动态类型的使用类型进行一些了解。

类:使用System.Type(任何时候都是反射出类型进行使用,难道不是吗?)

构造函数:System.Reflection.ConstructorInfo(发现类构造函数的属性并提供对构造函数元数据的访问权)

事件:System.Reflection.EventInfo(发现事件的属性并提供对事件元数据的访问权)

字段:System.Reflection.FieldInfo(发现字段属性并提供对字段元数据的访问权)

方法:System.Reflection.MemberInfo(获取有关成员属性的信息并提供对成员元数据的访问)

成员:System.Reflection.MemberInfo(获取有关成员属性的信息并提供对成员元数据的访问)

参数:System.Reflection.ParameterInfo(发现参数属性并提供对参数元数据的访问)

属性:System.Reflection.PropertyInfo (发现属性 (Property) 的属性 (Attribute) 并提供对属性 (Property) 元数据的访问)

同样这是一种延伸阅读,只是先对这些进行了解,如果不知道的话,可能对动态的使用类型就无法下手了。

今天我做了一个Demo,先上Demo吧,然后在来解释程序是如何执行的。

/动态创建的动态类型


public static Type DynamicCreateType()

{

//动态创建程序集

AssemblyName DemoName = new AssemblyName("DynamicAssembly");

AssemblyBuilder dynamicAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(DemoName, AssemblyBuilderAccess.RunAndSave);

//动态创建模块

ModuleBuilder mb = dynamicAssembly.DefineDynamicModule(DemoName.Name, DemoName.Name + ".dll");

//动态创建类MyClass

TypeBuilder tb = mb.DefineType("MyClass", TypeAttributes.Public);

//动态创建字段

FieldBuilder fb = tb.DefineField("myField", typeof(System.String), FieldAttributes.Private);

//动态创建构造函数

Type[] clorType = new Type[] { typeof(System.String) };

ConstructorBuilder cb1 = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, clorType);

//生成指令

ILGenerator ilg = cb1.GetILGenerator();//生成 Microsoft 中间语言 (MSIL) 指令

ilg.Emit(OpCodes.Ldarg_0);

ilg.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes));

ilg.Emit(OpCodes.Ldarg_0);

ilg.Emit(OpCodes.Ldarg_1);

ilg.Emit(OpCodes.Stfld, fb);

ilg.Emit(OpCodes.Ret);

//动态创建属性

PropertyBuilder pb = tb.DefineProperty("MyProperty", PropertyAttributes.HasDefault, typeof(string), null);

//动态创建方法

MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName;

MethodBuilder myMethod = tb.DefineMethod("get_Field", getSetAttr, typeof(string), Type.EmptyTypes);

//生成指令

ILGenerator numberGetIL = myMethod.GetILGenerator();

numberGetIL.Emit(OpCodes.Ldarg_0);

numberGetIL.Emit(OpCodes.Ldfld, fb);

numberGetIL.Emit(OpCodes.Ret);

//使用动态类创建类型

Type classType = tb.CreateType();

//保存动态创建的程序集 (程序集将保存在程序目录下调试时就在Debug下)

dynamicAssembly.Save(DemoName.Name + ".dll");

//创建类

return classType;

}

执行的主要方法

static void Main(string[] args)

{

//动态创建的类类型

Type classType = DynamicCreateType();

//调用有参数的构造函数

Type[] ciParamsTypes = new Type[] { typeof(string) };

object[] ciParamsValues = new object[] { "Hello World" };

ConstructorInfo ci = classType.GetConstructor(ciParamsTypes);

object Vector = ci.Invoke(ciParamsValues);

//调用方法

object[] methedParams=new object[]{};

Console.WriteLine(classType.InvokeMember("get_Property", BindingFlags.InvokeMethod, null, Vector, methedParams));

Console.ReadKey();

}

这个程序首先调用DynamicCreateType()方法创建动态类型,这跟第一章里帖出来的如何创建的代码几乎是一样的,另外保存了动态创建的程序集,我创建了一个类,类里创建了有一个字段、有一个参数的构造函数、一个属性、有一个参数的构造函数和一个方法。用有参数的构造函数来初始化字段myField,然后调用get_Field方法返回myField字段的值。控制台程序显示“Hello World!!!”

后面还会继续介绍动态创建和动态使用类,如何创建复杂的方法,特别是中间语言(MSIL)的生成。

默认分类 | 阅读 2002 次
文章评论,共0条
游客请输入验证码
浏览141420次
文章分类