您的位置:首页 > 编程语言 > C#

c# 动态生成继承类并实现序列化特性

2017-06-05 09:18 211 查看
项目来源

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[0]);

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 = 1001;
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.执行结果为

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: