Emit学习-基础篇-为动态类添加属性、构造函数、方法
2011-03-28 21:24
633 查看
我们通过一个计算A+B的动态类来演示如何为一个动态类添加属性、构造函数、方法,以及在方法中使用类中定义的属性,按照惯例,我们先给出要实现的动态类的C#代码,然后再针对C#代码给出相应的实现,代码如下:
前面的步骤和之前的斐波那契实现相同,这里我们直接从属性的定义开始。首先,我们通过TypeBuilder对象的DefineField方法来定义私有字段_a和_b,并为它们设置默认值0,代码如下:
- 定义私有字段_a和_b
然后我们通过TypeBuilder对象的DefineProperty方法分别定义属性A、B;接着再通过PropertyBuilder的SetGetMethod和SetSetMethod方法设置它们的get和set方法,至于get和set方法的IL代码的生成则和普通的Method定义相同,这里只列出属性A的定义,属性B与A相同,代码如下:
- 定义公有属性A和B
定义属性A的get和set方法
最后,我们来定义构造函数和Calc方法,构造函数的定义使用TypeBuilder的DefineConstructor方法,获得一个ConstructorBuilder对象,接下来就转入到跟普通的方法定义相同的步骤,代码如下:
定义构造函数和方法
- 定义构造函数
- 定义方法
到这里,我们终于完成了动态类的创建
public class Add { private int _a = 0; public int A { get { return _a; } set { _a = value; } } private int _b = 0; public int B { get { return _b; } set { _b = value; } } public Add(int a, int b) { _a = a; _b = b; } public int Calc() { return _a + _b; } }
前面的步骤和之前的斐波那契实现相同,这里我们直接从属性的定义开始。首先,我们通过TypeBuilder对象的DefineField方法来定义私有字段_a和_b,并为它们设置默认值0,代码如下:
- 定义私有字段_a和_b
FieldBuilder fieldABuilder = typeBuilder.DefineField("_a", typeof(Int32), FieldAttributes.Private); FieldBuilder fieldBBuilder = typeBuilder.DefineField("_b", typeof(Int32), FieldAttributes.Private); fieldABuilder.SetConstant(0); fieldBBuilder.SetConstant(0);
然后我们通过TypeBuilder对象的DefineProperty方法分别定义属性A、B;接着再通过PropertyBuilder的SetGetMethod和SetSetMethod方法设置它们的get和set方法,至于get和set方法的IL代码的生成则和普通的Method定义相同,这里只列出属性A的定义,属性B与A相同,代码如下:
- 定义公有属性A和B
PropertyBuilder propertyABuilder = typeBuilder.DefineProperty("A", PropertyAttributes.None, typeof(Int32), null); PropertyBuilder propertyBBuilder = typeBuilder.DefineProperty("B", PropertyAttributes.None, typeof(Int32), null);
定义属性A的get和set方法
//定义属性A的get方法 MethodBuilder getPropertyABuilder = typeBuilder.DefineMethod("get", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, typeof(Int32), Type.EmptyTypes); //生成属性A的get方法的IL代码,即返回私有字段_a ILGenerator getAIL = getPropertyABuilder.GetILGenerator(); getAIL.Emit(OpCodes.Ldarg_0); getAIL.Emit(OpCodes.Ldfld, fieldABuilder); getAIL.Emit(OpCodes.Ret); //定义属性A的set方法 MethodBuilder setPropertyABuilder = typeBuilder.DefineMethod("set", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null, new Type[] { typeof(Int32) }); //生成属性A的set方法的IL代码,即设置私有字段_a值为传入的参数1的值 ILGenerator setAIL = setPropertyABuilder.GetILGenerator(); setAIL.Emit(OpCodes.Ldarg_0); setAIL.Emit(OpCodes.Ldarg_1); setAIL.Emit(OpCodes.Stfld, fieldABuilder); setAIL.Emit(OpCodes.Ret); //设置属性A的get和set方法 propertyABuilder.SetGetMethod(getPropertyABuilder); propertyABuilder.SetSetMethod(setPropertyABuilder);
最后,我们来定义构造函数和Calc方法,构造函数的定义使用TypeBuilder的DefineConstructor方法,获得一个ConstructorBuilder对象,接下来就转入到跟普通的方法定义相同的步骤,代码如下:
定义构造函数和方法
- 定义构造函数
ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, new Type[] { typeof(Int32), typeof(Int32) }); ILGenerator ctorIL = constructorBuilder.GetILGenerator(); //加载参数1填充到私有字段_a ctorIL.Emit(OpCodes.Ldarg_0); ctorIL.Emit(OpCodes.Ldarg_1); ctorIL.Emit(OpCodes.Stfld, fieldABuilder); //加载参数2填充到私有字段_b ctorIL.Emit(OpCodes.Ldarg_0); ctorIL.Emit(OpCodes.Ldarg_2); ctorIL.Emit(OpCodes.Stfld, fieldBBuilder); ctorIL.Emit(OpCodes.Ret);
- 定义方法
MethodBuilder calcMethodBuilder = typeBuilder.DefineMethod("Calc", MethodAttributes.Public, typeof(Int32), Type.EmptyTypes); ILGenerator calcIL = calcMethodBuilder.GetILGenerator(); //加载私有字段_a calcIL.Emit(OpCodes.Ldarg_0); calcIL.Emit(OpCodes.Ldfld, fieldABuilder); //加载私有字段_b calcIL.Emit(OpCodes.Ldarg_0); calcIL.Emit(OpCodes.Ldfld, fieldBBuilder); //相加并返回结果 calcIL.Emit(OpCodes.Add); calcIL.Emit(OpCodes.Ret);
到这里,我们终于完成了动态类的创建
相关文章推荐
- Emit学习-基础篇-为动态类添加属性、构造函数、方法
- Emit学习-基础篇-为动态类添加属性、构造函数、方法
- Emit学习(3) - OpCodes - 动态添加属性、构造函数、方法
- JavaScript基础学习之-JavaScript权威指南--第八章函数属性方法构造函数
- iOS类添加方法、属性学习笔记
- Python学习笔记——动态添加属性与方法
- JavaScript基础学习之-JavaScript权威指南--8.7函数属性方法构造函数
- 【js学习笔记-049】---函数的属性、方法和构造函数
- 我的Python学习笔记(四):动态添加属性和方法
- js学习(一)-动态添加、修改、删除对象的属性和方法
- Kotlin学习记录(二)—— Kotlin的变量、属性、类、构造函数、继承、方法
- 织梦 DeDeCMS 添加自定义属性的方法(图文教程)
- 说说Android 两种为自定义组件添加属性的使用方法和区别
- ASP.NET MVC 学习7、为Model Class的字段添加验证属性(validation attribuate)
- javascript面向对象(给对象添加属性和方法的方式)
- Spring源码学习之:@Async 方法上添加该注解实现异步调用的原理
- Java学习笔记——子类调用父类属性方法
- [读书笔记]C#学习笔记五: C#3.0自动属性,匿名属性及扩展方法
- C++学习笔记5:从方法到属性(面向对象基础)
- 【代码学习】角色添加权限的方法,先删除,再添加。而不是用修改,这样很方便。