Csharp/C#教程:c#动态类型,及动态对象的创建,合并2个对象,map实例分享

经常会遇到这样的情况,我们在响应客户端请求的数据的时候需要对数据进行处理,比如数据库中的数据是int型,它可能表示某个枚举,或者其它的逻辑意义(数据库这样的设计可能是从数据安全性、存储量上等角度考虑),但是客户端显示的时候需要是它具体的意义。

这个时候我们的处理方式一般都是2中的,如果逻辑不复杂,且单一的话,直接修改sql语句就能处理好数据源,这个时候代码里面不需要处理什么。

但是如果逻辑复稍许复杂或者判断的情况有很多分支,我们不得不从代码角度来处理了。单个对象还好,多个对象比如是个list<T>,那就要循环对某个对象的字段进行XXX了。

进而衍生出了这就出现了DTO,Arg的中间对象,当然,我个人是很喜欢这样的设计的,但是某些时候也会偷懒不想写(多半情况我直接写代码生器批量生产),比如在测试的时候,在接私活的时候,在演示的时候,只为快速呈现想要的效果都懒得去屑,是的,你会说市面上不是有很多的map库,比如automap,tinymap,甚至json.net里面的动态特性重写,方法当然很多,但用一个大轮子来费力搞这么个小事,我觉得划不来。且轮子越来越大它要干的事越多,我可不想搞的那么复杂,嗯,就是这样,写了个。

具体的代码贴到下面,如果看明白,会很方便的扩展了或修改成自己想要的效果。

usingSystem.Dynamic; usingSystem.Reflection; usingSystem.Collections.Concurrent; privatestaticreadonlyConcurrentDictionary<RuntimeTypeHandle,PropertyInfo[]> DynamicObjectProperties=newConcurrentDictionary<RuntimeTypeHandle,PropertyInfo[]>(); privateIDictionary<string,Object>ToDynamicResult<T>(Tclassobj,Func<string,object,object>injectAct) whereT:IInjectClass,new() { vartype=typeof(T); varkey=type.TypeHandle; vardynamicResult=newExpandoObject()asIDictionary<string,Object>; PropertyInfo[]queryPts=null; DynamicObjectProperties.TryGetValue(key,outqueryPts); if(queryPts==null) { queryPts=type.GetProperties(); DynamicObjectProperties.TryAdd(key,queryPts); } foreach(varpinqueryPts) { varattributes=p.GetCustomAttributes(typeof(IngorePropertyAttribute),true); varcolumnMapping=attributes.FirstOrDefault(); if(columnMapping!=null)continue; var_name=p.Name; var_value=p.GetValue(classobj,null); object_tempvalue=_value; if(injectAct!=null)_tempvalue=injectAct.Invoke(_name,_value); //varvalue=Convert.ChangeType(value,typeof(string)); dynamicResult.Add(p.Name,_tempvalue); } returndynamicResult; } ///<summary> ///支持动态输出的对象接口 ///</summary> publicinterfaceIInjectClass { } ///<summary> ///动态输出时忽略此标记的属性 ///</summary> publicclassIngorePropertyAttribute:Attribute { }

下面我们测试一个:

publicclasskk:IInjectClass { publicstringaa{get;set;} publicintbb{get;set;} [IngoreProperty] publicboolcc{get;set;} publicDateTimedd{get;set;} }kkist=newkk(); ist.aa="aaa"; ist.bb=123; ist.cc=false; ist.dd=DateTime.Now; vartt=ToDynamicResult<kk>(ist,(k,v)=> { if(k!="aa")returnv; returnv+"(改变了哦)"; }); varjson=Tools.JsonUtils.JsonSerializer(tt); json=json+"<br/><br/>"+Tools.JsonUtils.JsonSerializer(ToDynamicResult<kk>( newkk { aa="test", bb=789, cc=true, dd=DateTime.Now.AddDays(2) },null)); Response.Write(json);

您可以重新构造带参数的特性或者修改injectAct对象,改成适合自己的

下面写个测试,改成表达式树最好了,先上个码

usingSystem; usingSystem.Linq; usingSystem.Dynamic; usingSystem.Reflection; usingSystem.Linq.Expressions; usingSystem.Collections.Generic; usingSystem.Collections.Concurrent; namespaceTools { publicclassClass2Map { privatestaticreadonlyConcurrentDictionary<RuntimeTypeHandle,PropertyInfo[]> DynamicObjectProperties=newConcurrentDictionary<RuntimeTypeHandle,PropertyInfo[]>(); privatestaticPropertyInfo[]GetObjectProperties<T>() { vartype=typeof(T); varkey=type.TypeHandle; PropertyInfo[]queryPts=null; DynamicObjectProperties.TryGetValue(key,outqueryPts); if(queryPts==null) { queryPts=type.GetProperties(); DynamicObjectProperties.TryAdd(key,queryPts); } returnqueryPts; } ///<summary> ///单个对象映射 ///</summary> ///<typeparamname="T">类型</typeparam> ///<paramname="source">实例</param> ///<paramname="injectAct">map方法集</param> ///<returns>映射后的动态对象</returns> publicstaticIDictionary<string,Object>DynamicResult<T>(Tsource,paramsMapCondition[]injectAct)//whereT:ICustomMap { varqueryPts=GetObjectProperties<T>(); vardynamicResult=newExpandoObject()asIDictionary<string,Object>; foreach(varpinqueryPts) { varattributes=p.GetCustomAttributes(typeof(IngoreProperty),true); if(attributes.FirstOrDefault()!=null)continue; var_name=p.Name;//原来是属性名 var_value=p.GetValue(source,null);//原来的属性值 object_resultvalue=_value;//最终的映射值 if(injectAct!=null) { string_tempname=null; varcondition=injectAct.FirstOrDefault(x=>x.Orginal==_name); if(CheckChangeInfo(condition,out_tempname)) { _resultvalue=condition.fn.Invoke(_value); dynamicResult.Add(_tempname??_name,_resultvalue); continue; } } //varvalue=Convert.ChangeType(value,typeof(string)); dynamicResult.Add(_name,_resultvalue); } returndynamicResult; } ///<summary> ///合并2个对象 ///</summary> ///<typeparamname="TSource">对象1类型</typeparam> ///<typeparamname="TTarget">对象2类型</typeparam> ///<paramname="s">对象1实例</param> ///<paramname="t">对象2实例</param> ///<returns>合并后的动态对象</returns> publicstaticIDictionary<string,Object>MergerObject<TSource,TTarget>(TSources,TTargett) { vartargetPts=GetObjectProperties<TSource>(); PropertyInfo[]mergerPts=null; var_type=t.GetType(); mergerPts=_type.Name.Contains("<>")?_type.GetProperties():GetObjectProperties<TTarget>(); vardynamicResult=newExpandoObject()asIDictionary<string,Object>; foreach(varpintargetPts) { varattributes=p.GetCustomAttributes(typeof(IngoreProperty),true); if(attributes.FirstOrDefault()!=null)continue; dynamicResult.Add(p.Name,p.GetValue(s,null)); } foreach(varpinmergerPts) { varattributes=p.GetCustomAttributes(typeof(IngoreProperty),true); if(attributes.FirstOrDefault()!=null)continue; dynamicResult.Add(p.Name,p.GetValue(t,null)); } returndynamicResult; } ///<summary> ///合并2个对象 ///</summary> ///<typeparamname="TSource">对象1类型</typeparam> ///<typeparamname="TTarget">对象2类型</typeparam> ///<paramname="s">对象1实例</param> ///<paramname="t">对象2实例</param> ///<returns>合并后的动态对象</returns> publicstaticList<IDictionary<string,Object>>MergerListObject<TSource,TTarget>(List<TSource>s,TTargett) { vartargetPts=GetObjectProperties<TSource>(); PropertyInfo[]mergerPts=null; var_type=t.GetType(); mergerPts=_type.Name.Contains("<>")?_type.GetProperties():GetObjectProperties<TTarget>(); varresult=newList<IDictionary<string,Object>>(); s.ForEach(x=> { vardynamicResult=newExpandoObject()asIDictionary<string,Object>; foreach(varpintargetPts) { varattributes=p.GetCustomAttributes(typeof(IngoreProperty),true); if(attributes.FirstOrDefault()!=null)continue; dynamicResult.Add(p.Name,p.GetValue(x,null)); } foreach(varpinmergerPts) { varattributes=p.GetCustomAttributes(typeof(IngoreProperty),true); if(attributes.FirstOrDefault()!=null)continue; dynamicResult.Add(p.Name,p.GetValue(t,null)); } result.Add(dynamicResult); }); returnresult; } privatestaticboolCheckChangeInfo(MapConditioncondition,outstringname) { name=null; boolresult=condition!=null&& condition.fn!=null&& !string.IsNullOrWhiteSpace(condition.Orginal);//&& //!string.IsNullOrWhiteSpace(condition.NewName); if(result) { vartemp=condition.NewName; name=(string.IsNullOrWhiteSpace(temp)||temp.Trim().Length==0)?null:temp; } returnresult; } } }

测试一下:

List<KeyValue>kk=newList<KeyValue> { newKeyValue{key="aaa",value="111"}, newKeyValue{key="bbb",value="222"}, newKeyValue{key="ccc",value="333"}, newKeyValue{key="ddd",value="444"}, }; varresult=Class2Map.MergerListObject<KeyValue,dynamic>(kk,new{p="jontest"}); varjson=JsonUtils.JsonSerializer(result); Response.Write(json);

输出如下:

[{"key":"aaa","value":"111","p":"jontest"},{"key":"bbb","value":"222","p":"jontest"},{"key":"ccc","value":"333","p":"jontest"},{"key":"ddd","value":"444","p":"jontest"}] varresult=Class2Map.MergerObject<KeyValue,dynamic>( newKeyValue{key="aaa",value="111"}, new{p="jontest"} ); varjson=JsonUtils.JsonSerializer(result); Response.Write(json);

输出如下:

{"key":"aaa","value":"111","p":"jontest"}

上述就是C#学习教程:c#动态类型,及动态对象的创建,合并2个对象,map实例分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/907722.html

(0)
上一篇 2021年10月25日
下一篇 2021年10月25日

精彩推荐