利用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. web-打印

    项目前景 由于之前的打印是客户端程序,也就是winform做的,现在需要改版成网页版,其他功能都能够很好的实现,就是在打印上遇到一些难点.由于第一次做打印功能,刚开始照搬winform中调用word文 ...

  2. OpenGL ES 2.0 光照

    基本的光照 光照分成了3种组成元素(3个通道):环境光.散射光以及镜面光. 材质的反射系数实际指的就是物体被照射处的颜色,散射光强度指的是散射光中的RGB(红.绿.蓝)3个色彩通道的强度. 环境光 指 ...

  3. C/C++中的sizeof

    代码: #include <iostream> #include <string> using namespace std; int main(){ char s1[]=&qu ...

  4. jQuery 文字截取

    HTML <div class="summary">    <p class="news">业内知道,当赵科林“过档”联想之初,恰逢联想 ...

  5. python列表sort方法的两个参数key, reverse

    使用列表的sort方法可以进行排序,其中有两个参数用来表示排序的方式,代码: In [7]: a = ['x11','abc323','e26','112ddd'] In [8]: a.sort(ke ...

  6. [转]详解AppDelegate/UIApplication

    一.UIApplication 1.简单介绍 (1)UIApplication对象是应用程序的象征,一个UIApplication对象就代表一个应用程序. (2)每一个应用都有自己的UIApplica ...

  7. 用C实现字符串分割并返回所有子串

    #include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h> ...

  8. javax.net.ssl.SSLException: java.lang.UnsupportedOperationException

    Loading KeyStore C:\Tool\jdk1.7.0_71\jre\lib\security\jssecacerts... Opening connection to www.googl ...

  9. DSASync: Managing End-to-End Connections in Dynamic Spectrum Access Wireless LANs

    其实跟上一篇是同一篇文章.不过上一篇是发表在IEEE Secon2010了,这篇是后来又增加了部分内容后的一版,收录在IEEE/ACM TRANSACTIONS ON NETWORKING, VOL. ...

  10. discuz@功能的代码

    //转载 $atlist = $atlist_tmp = $ateduids = array(); preg_match_all("/@([^\r\n]*?)\s/i", $mes ...