利用TypeBuilder是可以动态创建一个类型,现在有个需求,动态生成一个dll,创建类型EmployeeEx,需要继承原dll里面的Employee类,并包含Employee类上的所有类标记。

 

网上有很多例子,

//创建TypeBuilder。
TypeBuilder myTypeBuilder = myModBuilder.DefineType(typeName,
TypeAttributes.Public); myTypeBuilder.SetParent(type);

 

大概处理方式如下:

CustomAttributeBuilder customAttributeBuilder = new CustomAttributeBuilder(typeof(SerializableAttribute).GetConstructor(Type.EmptyTypes), new Type[] { });
myTypeBuilder.SetCustomAttribute(customAttributeBuilder); att = type.GetCustomAttributes(typeof(DefaultPropertyAttribute), false);
if (att != null && att.Length > 0) {
DefaultPropertyAttribute dea = att[0] as DefaultPropertyAttribute;
customAttributeBuilder = new CustomAttributeBuilder(typeof(DefaultPropertyAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { dea.Name });
myTypeBuilder.SetCustomAttribute(customAttributeBuilder);
}

 

但是,这些都是已知类标记是Serializable或者DefaultProperty,如果原dll中的Employee再加个自定义标记,我们还需要再改程序,如何能够动态继承到类标记,TypeBuilder.SetCustomAttribute提供了2个重载SetCustomAttribute(CustomAttributeBuilder customBuilder)和SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)。这两个都是需要ConstructorInfo来构造类标记。而我们通过类型Employee得到的类标记是通过反射得到的object[] atts = type.GetCustomAttributes(false);这是object数组,不能直接给ConstructorInfo使用。

 

所以就有了下面的代码,来动态产生标记。

#region 标记
object[] atts = type.GetCustomAttributes(false);
if (atts != null && atts.Length > 0) {
foreach (Attribute item in atts) {
if (item == null) continue;
try {
CustomAttributeBuilder c = null;
ConstructorInfo[] conInfos = item.GetType().GetConstructors();
ConstructorInfo cons = conInfos[conInfos.Length - 1];
ParameterInfo[] args = cons.GetParameters();
List<Type> argsList = new List<Type>();
List<object> argsValue = new List<object>();
if (args.Length > 0) {
foreach (var arg in args) {
argsList.Add(arg.ParameterType);
PropertyInfo pi = item.GetType().GetProperty(arg.Name.Substring(0, 1).ToUpper() + arg.Name.Substring(1));//微软规则首字母小写
if (pi != null) {
argsValue.Add(pi.GetValue(item, null));
} else {
pi = item.GetType().GetProperty(arg.Name.Remove(0, 1));//我们的规则p+Name
if (pi != null) {
argsValue.Add(pi.GetValue(item, null));
} else {
argsValue.Add(null);
}
}
}
}
PropertyInfo[] pis = item.GetType().GetProperties();
if (pis.Length > 0) {
List<PropertyInfo> piList = new List<PropertyInfo>();
List<object> valueList = new List<object>();
object[] pValues = new object[pis.Length];
for (int i = 0; i < pis.Length; i++) {
if (pis[i].CanWrite) {
pValues[i] = pis[i].GetValue(item, null);
if (pValues[i] != null) {
piList.Add(pis[i]);
valueList.Add(pValues[i]);
}
}
}
if (piList.Count > 0) {
c = new CustomAttributeBuilder(cons, argsValue.ToArray(), piList.ToArray(), valueList.ToArray());
} else {
c = new CustomAttributeBuilder(cons, argsValue.ToArray());
}
} else {
c = new CustomAttributeBuilder(cons, argsValue.ToArray());
}
myTypeBuilder.SetCustomAttribute(c);
} catch (Exception ex) {
throw new Exception(string.Format("{0}的标记[{1}]重写异常:{2}", typeName, item.ToString(),ex.ToString()));
}
}
}

关于Emit中动态类型TypeBuilder创建类标记的一点思考的更多相关文章

  1. c# 把一个匿名对象赋值给一个Object类型的变量后,怎么取这个变量? c# dynamic动态类型和匿名类 详解C# 匿名对象(匿名类型)、var、动态类型 dynamic 深入浅析C#中的var和dynamic

    比如有一个匿名对象,var  result =......Select( a=>new {  id=a.id, name=a.name});然后Object  obj =  result ;我怎 ...

  2. 自己动手之使用反射和泛型,动态读取XML创建类实例并赋值

    前言: 最近小匹夫参与的游戏项目到了需要读取数据的阶段了,那么觉得自己业余时间也该实践下数据相关的内容.那么从哪入手呢?因为用的是Unity3d的游戏引擎,思来想去就选择了C#读取XML文件这个小功能 ...

  3. mvc中动态给一个Model类的属性设置验证

    原文:mvc中动态给一个Model类的属性设置验证 在mvc中有自带的验证机制,比如如果某个字段的类型是数字或者日期,那么用户在输入汉字或者英文字符时,那么编译器会自动验证并提示用户格式不正确,不过这 ...

  4. Swift微博项目--Swift中通过类名字符串创建类以及动态加载控制器的实现

    Swift中用类名字符串创建类(用到了命名空间) OC中可以直接通过类名的字符串转换成对应的类来操作,但是Swift中必须用到命名空间,也就是说Swift中通过字符串获取类的方式为NSClassFro ...

  5. Object-C中动态类型对象相关操作汇总

    Object-C(以后简称OC)中有id类型,相对于明确定义类型的静态类型,称为动态类型. 使用动态类型,配合多态(不同类型拥有同名方法),动态绑定(运行时决定实际调用的方法)可以将很多判断延迟到运行 ...

  6. c# dynamic动态类型和匿名类

    dynamic类型 简单示例 dynamic expando = new System.Dynamic.ExpandoObject(); //动态类型字段 可读可写 expando.Id = 1; e ...

  7. Unity 3D 中动态字体的创建

    原创不易,转载请注明转自: http://blog.csdn.net/u012413679/article/details/26232453 ---- kosion 1.载入NGUI插件包,载入完毕后 ...

  8. Java中Date类型的工具类

    package com.mytripod.util; import java.text.DateFormat; import java.text.SimpleDateFormat; import ja ...

  9. Python中type()详解:动态创建类

    众所周知: type()函数可以查看变量的类型: 先看一个简单的列子来看一下type查看变量类型 class Animal(): pass a=Animal() print(type(a)) prin ...

随机推荐

  1. 《第一行代码》学习笔记7-活动Activity(5)

    1.Intent中只能指定一个action,但却能指定多个category. 2.使用隐式Intent,不仅可以启动自己程序内的活动,还可以启动其他程序的活动,使得Android应用程序之间 的功能共 ...

  2. java NumberForMate的使用

    有时候我们需要将数字转化为字符串,并且转化后的长度要一定.比如00012这种类型.这时候我们就可以使用NumberForMate这个方法: NumberFormat numberFormat = Nu ...

  3. C#中子窗体获取父窗体中控件的内容

    今天在做一个联系人管理的C#设计时,遇到了这个问题,我需要将父窗体中的textBox中的值传到子窗体并进行数据库查询操作,我用了new 父窗体().textBox.text;来进行值传递,然而并无卵用 ...

  4. 费马小定理&欧拉定理

    在p是素数的情况下,对任意整数x都有xp≡x(mod p).这个定理被称作费马小定理其中如果x无法被p整除,我们有xp-1≡1(mod p).利用这条性质,在p是素数的情况下,就很容易求出一个数的逆元 ...

  5. 分数(有理数)的四则运算PAT1088

    2015-02-05 PAT- B1088. Rational Arithmetic (20) http://www.patest.cn/contests/pat-a-practise/1088 #i ...

  6. c# 输出excel、word实例只需一行代码

    第一.首先下载 WindICFrameNet.dll 下载地址:http://pan.baidu.com/s/1dDBqC9r 第二.前台代码 <div style="display: ...

  7. 使用QtCreator作为ROS调试器

    如果你用过QtCreator,你一定会喜欢上它. 流畅的速度,强大的功能,优雅的外观,友好的界面,一切让人如此舒服.而且它支持从命令行作为调试器启动,只需加上-debug exe即可. 因此我想如果能 ...

  8. 感知机(perceptron)

    二类分类的线性分类模型,属于判别模型,利用梯度下降法对损失函数进行极小化求得感知机模型分为原始形式和对偶形式,是神经网络和支持向量机的基础 由输入控件到输出控件的如下函数: f(x)=sign(W.X ...

  9. dubbo初体验

    最近需要开发部门中某个大数据量的提取的功能,加到了一个ElasticSearch的群.在群里听说到一个框架叫dubbo,阿里系开源软件.听到群友谈的神乎其神的,什么什么功能切分多协议栈,高并发等等等. ...

  10. 【转】如何测试CTS4.0 -- 不错

    原文网址:http://blog.csdn.net/subsist/article/details/7209341/ CTS4.0测试步骤 V1.2 (更新到CTS4.0 R3)     第一:平台准 ...