c# 动态生成继承类并实现序列化特性
项目来源
App传过来的字段是动态的,希望能保证扩展性,返回时,把所需要的字段与数据融合后再返回过去
数据是第3方来源的,但是序列化后的结果又希望能并列返回
如:App传过来 一个设备Id,客户Id等信息(该信息不定,特定的窗口传过来的字段值不同,如一个hash表)
返回的结果是一个地址(省,市,县等字段)(再merge 设备id,客户id等字段)
简单的结果集可以用 字典来返回,但是复杂的结果集就不适合了(代码必须相对优雅)
解决方案: 将传过来的字段保存到字典里,然后 生成动态类继承数据类,并将字典数据一一对应到动态类的字段里.
1.原始类
public class Address
{
[JsonProperty(PropertyName = "province"), Description("省份")]
public string Province { get; set; } [JsonProperty(PropertyName = "city"), Description("城市")]
public string City { get; set; }
}
2.动态扩展该类(增加一个id属性,和一个 县市 属性)
var assemblyName = new AssemblyName("DynamicProxy");
var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName,
AssemblyBuilderAccess.RunAndSave);
var moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule", "DynamicProxy.dll");
//定义公开,继承Object,无接口的类
var typeBuilder = moduleBuilder.DefineType("AddressAddtional", TypeAttributes.Public | TypeAttributes.Serializable, typeof(Address), new Type[]);
var fieldId = typeBuilder.DefineField("id", typeof(int), FieldAttributes.Private);
var fieldName = typeBuilder.DefineField("county", typeof(string), FieldAttributes.Private);
var methodGetId = typeBuilder.DefineMethod("GetId", MethodAttributes.Public, typeof(int), null);
var methodSetId = typeBuilder.DefineMethod("SetId", MethodAttributes.Public, null, new Type[] { typeof(int) });
var ilGetId = methodGetId.GetILGenerator();
ilGetId.Emit(OpCodes.Ldarg_0);//this 入栈
ilGetId.Emit(OpCodes.Ldfld,fieldId);
ilGetId.Emit(OpCodes.Ret);
var ilSetId = methodSetId.GetILGenerator();
ilSetId.Emit(OpCodes.Ldarg_0);//this 入栈
ilSetId.Emit(OpCodes.Ldarg_1);//参数 入栈
ilSetId.Emit(OpCodes.Stfld, fieldId);
ilSetId.Emit(OpCodes.Ret);
var methodGetCounty = typeBuilder.DefineMethod("GetCounty", MethodAttributes.Public, typeof(string), null);
var methodSetCounty = typeBuilder.DefineMethod("SetCounty", MethodAttributes.Public, null, new Type[] { typeof(string) });
var ilGetCounty = methodGetCounty.GetILGenerator();
ilGetCounty.Emit(OpCodes.Ldarg_0);//this 入栈
ilGetCounty.Emit(OpCodes.Ldfld, fieldName);
ilGetCounty.Emit(OpCodes.Ret);
var ilSetCounty = methodSetCounty.GetILGenerator();
ilSetCounty.Emit(OpCodes.Ldarg_0);//this 入栈
ilSetCounty.Emit(OpCodes.Ldarg_1);//参数 入栈
ilSetCounty.Emit(OpCodes.Stfld, fieldName);
ilSetCounty.Emit(OpCodes.Ret);
var propertyId = typeBuilder.DefineProperty("Id", PropertyAttributes.None, typeof (int), null);
CustomAttributeBuilder customAttributeBuilder = new CustomAttributeBuilder(typeof(DescriptionAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { "地址Id" });
CustomAttributeBuilder customAttributeBuilder2 = new CustomAttributeBuilder(typeof(JsonPropertyAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { "id" });
propertyId.SetCustomAttribute(customAttributeBuilder);//字段描述
propertyId.SetCustomAttribute(customAttributeBuilder2);//JsonProperty
propertyId.SetGetMethod(methodGetId);
propertyId.SetSetMethod(methodSetId);
var propertyCounty = typeBuilder.DefineProperty("County", PropertyAttributes.None, typeof(string), null);
customAttributeBuilder = new CustomAttributeBuilder(typeof(DescriptionAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { "县区" });
customAttributeBuilder2 = new CustomAttributeBuilder(typeof(JsonPropertyAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { "county" });
propertyCounty.SetCustomAttribute(customAttributeBuilder);//字段描述
propertyCounty.SetCustomAttribute(customAttributeBuilder2);//JsonProperty
propertyCounty.SetGetMethod(methodGetCounty);
propertyCounty.SetSetMethod(methodSetCounty);
var dynamicType = typeBuilder.CreateType();
assemblyBuilder.Save("DynamicProxy.dll");
instance = Activator.CreateInstance(dynamicType);
instance.Id = ;
instance.County = "天河区";
instance.Province = "广东省";
instance.City = "广州市";
Console.WriteLine(JsonHelper.ToJson(instance) );
#endregion
3.动态生成的dll,代码如下(使用ILSpy查看)
public class AddressAddtional : Address
{
private int id;
private string county;
[JsonProperty("id"), Description("地址Id")]
public int Id
{
get
{
return this.id;
}
set
{
this.id = value;
}
}
[JsonProperty("county"), Description("县区")]
public string County
{
get
{
return this.county;
}
set
{
this.county = value;
}
} }
4.执行结果为

c# 动态生成继承类并实现序列化特性的更多相关文章
- 根据数据库记录动态生成C#类及其公共属性并动态执行的解决方案
原文:根据数据库记录动态生成C#类及其公共属性并动态执行的解决方案 问题: C#中,想动态产生这么一个类: public class StatisticsData { public ...
- 分析JVM动态生成的类
总结思考:让jvm创建动态类及其实例对象,需要给它提供哪些信息? 三个方面: 1.生成的类中有哪些方法,通过让其实现哪些接口的方式进行告知: 2.产生的类字节码必须有个一个关联的类加载器对象: 3.生 ...
- Java基础---Java---基础加强---类加载器、委托机制、AOP、 动态代理技术、让动态生成的类成为目标类的代理、实现Spring可配置的AOP框架
类加载器 Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader,AppClassLoader 类加载器也是Jav ...
- JAVA基础加强(张孝祥)_类加载器、分析代理类的作用与原理及AOP概念、分析JVM动态生成的类、实现类似Spring的可配置的AOP框架
1.类加载器 ·简要介绍什么是类加载器,和类加载器的作用 ·Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader ...
- Emit动态生成代理类用于监控对象的字段修改
利用Emit动态生成代理对象监控对象哪些字段被修改,被修改为什么值 被Register的对象要监控的值必须是Virtual虚类型 必须使用CreateInstance创建对象 必须使用DynamicP ...
- Java——动态生成POJO类
package com.java.test.dynamicpojo; import java.io.ByteArrayOutputStream; import java.io.IOException; ...
- 动态生成Person类的对象 代码参考
#include <iostream> #include <string> using namespace std; class Person { private: strin ...
- Java中动态代理技术生成的类与原始类的区别 (转)
用动态代理的时候,对它新生成的类长什么样子感到好奇.有幸通过一些资料消除了心里的疑惑. 平时工作使用的Spring框架里面有一个AOP(面向切面)的机制,只知道它是把类重新生成了一遍,在切面上加上了后 ...
- Java中动态代理技术生成的类与原始类的区别
用动态代理的时候,对它新生成的类长什么样子感到好奇.有幸通过一些资料消除了心里的疑惑. 平时工作使用的Spring框架里面有一个AOP(面向切面)的机制,只知道它是把类重新生成了一遍,在切面上加上了后 ...
随机推荐
- 使用Python定时执行一任务,自动登录某web系统,生成报表,然后发送邮件给指定人员
一.项目需求 每周从A系统生成一张Excel报表,发送此报表给指定人员,相关人员依据此报表去完成后续的工作. 项目限制: 1.无法通过EDI系统交互的方式从后台读取数据 2.由于公司网络环境限制,不能 ...
- 在IE11(Win8)中检查up6.2配置
1.按F12,打开调试模式 2.打开调试程序选项卡 说明:在调试程序选项卡中可看到IE加载的脚本信息是否正确.因为IE有缓存,导致脚本有时不是最新的. 3.打开脚本,up6.js ...
- delphi json用法
用法:uses Superobject, Sperjsondelphi里有json单元. procedure TForm2.SuperObjectClick(Sender: TObject); var ...
- samba服务器共享开发【windows下开发linux网站】
//@author:yuan<turing_zhy@163.com> //@date:2018-08-05 //注:码字不易转载请注明出处 //环境准备:ubuntu1~16.04.4 1 ...
- HackTwo
使用延迟加载以及避免代码重复 一.概要: <include />标签是整理布局的有效工具,提供了合理组织XML布局文件的有效方法. ViewStub是实现延迟加载视图的优 ...
- angular 父组件调用子组件
import { Component, OnInit, ViewChild } from '@angular/core'; @Component({ selector: 'app-child', te ...
- NSKeyedArchiver数据归档
前言 在 OC 语言中,归档是一个过程,即用某种格式来保存一个或多个对象,以便以后还原这些对象. 通常,这个过程包括将(多个)对象写入文件中,以便以后读取该对象.可以使用归档的方法进行对象的深复制. ...
- 【bzoj3930】选数 容斥原理+暴力
Description 我们知道,从区间[L,H](L和H为整数)中选取N个整数,总共有(H-L+1)^N种方案.小z很好奇这样选出的数的最大公约数的规律,他决定对每种方案选出的N个整数都求一次最大公 ...
- DHCP与PPPOE 区别
1.静态IP的方式,如果是占用一个INTERNET的IP的话,上网都是很贵的,当然这个也是最方便的,开机就能上网,不用做任何拨号或者认证的过程.2.PPPOE,只是多了一个获得IP的过程,一旦获得了I ...
- java学习笔记之位运算符
java的位运算符主要针对二进制数的位进行逻辑运算,主要包括以下几种的位运算符 1.与运算符(&) 与运算符的使用规律是两个操作数中位为1的时候结果为1,否则都是0,例如 3&5=1 ...