项目来源

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# 动态生成继承类并实现序列化特性的更多相关文章

  1. 根据数据库记录动态生成C#类及其公共属性并动态执行的解决方案

    原文:根据数据库记录动态生成C#类及其公共属性并动态执行的解决方案 问题: C#中,想动态产生这么一个类: public class StatisticsData    {        public ...

  2. 分析JVM动态生成的类

    总结思考:让jvm创建动态类及其实例对象,需要给它提供哪些信息? 三个方面: 1.生成的类中有哪些方法,通过让其实现哪些接口的方式进行告知: 2.产生的类字节码必须有个一个关联的类加载器对象: 3.生 ...

  3. Java基础---Java---基础加强---类加载器、委托机制、AOP、 动态代理技术、让动态生成的类成为目标类的代理、实现Spring可配置的AOP框架

    类加载器 Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader,AppClassLoader 类加载器也是Jav ...

  4. JAVA基础加强(张孝祥)_类加载器、分析代理类的作用与原理及AOP概念、分析JVM动态生成的类、实现类似Spring的可配置的AOP框架

    1.类加载器 ·简要介绍什么是类加载器,和类加载器的作用 ·Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader ...

  5. Emit动态生成代理类用于监控对象的字段修改

    利用Emit动态生成代理对象监控对象哪些字段被修改,被修改为什么值 被Register的对象要监控的值必须是Virtual虚类型 必须使用CreateInstance创建对象 必须使用DynamicP ...

  6. Java——动态生成POJO类

    package com.java.test.dynamicpojo; import java.io.ByteArrayOutputStream; import java.io.IOException; ...

  7. 动态生成Person类的对象 代码参考

    #include <iostream> #include <string> using namespace std; class Person { private: strin ...

  8. Java中动态代理技术生成的类与原始类的区别 (转)

    用动态代理的时候,对它新生成的类长什么样子感到好奇.有幸通过一些资料消除了心里的疑惑. 平时工作使用的Spring框架里面有一个AOP(面向切面)的机制,只知道它是把类重新生成了一遍,在切面上加上了后 ...

  9. Java中动态代理技术生成的类与原始类的区别

    用动态代理的时候,对它新生成的类长什么样子感到好奇.有幸通过一些资料消除了心里的疑惑. 平时工作使用的Spring框架里面有一个AOP(面向切面)的机制,只知道它是把类重新生成了一遍,在切面上加上了后 ...

随机推荐

  1. c语言打印空白星号矩形

    用户输入一个数字N,输出一个N*N的空心矩形,N最小为3 效果如下: 思路是这样的,首先拿到这道题是没有思路的,但我们可以举几个例子,当N等于3的情况,当N=5的情况,发现第一行和最后一行是相同的,而 ...

  2. DataTable 设置primarykey 后进行 Merge操作

    1.先查看概念 可以看highplayer博客 http://blog.csdn.net/highplayer/article/details/6613817 2. protected void st ...

  3. 使用Sqlserver事务发布实现数据同步(转)

    出处:http://www.cnblogs.com/daizhj/archive/2009/11/18/1605293.html 事务的功能在sqlserver中由来已久,因为最近在做一个数据同步方案 ...

  4. ASP.NET 5 Middleware, Or Where Has My HttpModule Gone?

    31 March 2015 13:22 ASP.NET 5 has been largely rewritten from the ground up, and incorporates some r ...

  5. 编写高质量代码改善C#程序的157个建议——建议14: 正确实现浅拷贝和深拷贝

    建议14: 正确实现浅拷贝和深拷贝 为对象创建副本的技术称为拷贝(也叫克隆).我们将拷贝分为浅拷贝和深拷贝. 浅拷贝 将对象中的所有字段复制到新的对象(副本)中.其中,值类型字段的值被复制到副本中后, ...

  6. Linux下ffmpeg安装与开发配置

    Linux下ffmpeg安装与开发配置   1. ffmpeg安装 安装环境: ubuntu 12.04 (1)删除已安装的文件,避免冲突 sudo apt-get remove ffmpeg x26 ...

  7. Javascript脚本 : eval()函数

    Javascript 中 eval(X)函数 是将参数 当做语句来执行 var number1='1+2'; alert(number1); 输出为 '12': var number2=eval('1 ...

  8. 用css画的一个图形 空心正方形+四边四色

    div{ width: 100px; height: 100px; border: 100px solid black; border-left-color:darkcyan; border-righ ...

  9. JS Img对象获取图片高度宽度(兼容Chrome)

    一般获取图片高度宽度的写法: var img = new Image();img.src = imgsrc;var imgWH = CalcImgTiple(img.width, img.height ...

  10. whisper简介

    以太坊系列之二十 以太坊中的基础应用whisper 以太坊系列之二十 以太坊中的基础应用whisper 1 whisper介绍 2 whisper rpc模块 3 whisper中的消息 4 消息的加 ...