c#动态类型,及动态对象的创建,合并2个对象,map实例
经常会遇到这样的情况,我们在响应客户端请求的数据的时候需要对数据进行处理,比如数据库中的数据是int型,它可能表示某个枚举,或者其它的逻辑意义(数据库这样的设计可能是从数据安全性、存储量上等角度考虑),但是客户端显示的时候需要是它具体的意义。
这个时候我们的处理方式一般都是2中的,如果逻辑不复杂,且单一的话,直接修改sql语句就能处理好数据源,这个时候代码里面不需要处理什么。
但是如果逻辑复稍许复杂或者判断的情况有很多分支,我们不得不从代码角度来处理了。单个对象还好,多个对象比如是个list<T>,那就要循环对某个对象的字段进行XXX了。
进而衍生出了这就出现了DTO,Arg的中间对象,当然,我个人是很喜欢这样的设计的,但是某些时候也会偷懒不想写(多半情况我直接写代码生器批量生产),比如在测试的时候,在接私活的时候,在演示的时候,只为快速呈现想要的效果 都懒得去屑,是的,你会说市面上不是有很多的map库,比如automap,tinymap,甚至json.net里面的动态特性重写,方法当然很多,但用一个大轮子来费力搞这么个小事,我觉得划不来。且轮子越来越大它要干的事越多,我可不想搞的那么复杂,嗯,就是这样,写了个。
具体的代码贴到下面,如果看明白,会很方便的扩展了或修改成自己想要的效果。
using System.Dynamic; using System.Reflection; using System.Collections.Concurrent; private static readonly ConcurrentDictionary<RuntimeTypeHandle, PropertyInfo[]> DynamicObjectProperties = new ConcurrentDictionary<RuntimeTypeHandle, PropertyInfo[]>(); private IDictionary<string, Object> ToDynamicResult<T>(T classobj, Func<string, object, object> injectAct) where T : IInjectClass, new() { var type = typeof(T); var key = type.TypeHandle; var dynamicResult = new ExpandoObject() as IDictionary<string, Object>; PropertyInfo[] queryPts = null; DynamicObjectProperties.TryGetValue(key, out queryPts); if (queryPts == null) { queryPts = type.GetProperties(); DynamicObjectProperties.TryAdd(key, queryPts); } foreach (var p in queryPts) { var attributes = p.GetCustomAttributes(typeof(IngorePropertyAttribute), true); var columnMapping = 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); //var value = Convert.ChangeType(value,typeof(string)); dynamicResult.Add(p.Name, _tempvalue); } return dynamicResult; } /// <summary> /// 支持动态输出的对象接口 /// </summary> public interface IInjectClass { } /// <summary> /// 动态输出时忽略此标记的属性 /// </summary> public class IngorePropertyAttribute : Attribute { }
下面我们测试一个:
public class kk : IInjectClass { public string aa { get; set; } public int bb { get; set; } [IngoreProperty] public bool cc { get; set; } public DateTime dd { get; set; } }kk ist = new kk(); ist.aa = "aaa"; ist.bb = 123; ist.cc = false; ist.dd = DateTime.Now; var tt = ToDynamicResult<kk>(ist, (k, v) => { if (k != "aa") return v; return v + "(改变了哦)"; }); var json = Tools.JsonUtils.JsonSerializer(tt); json = json + "<br /><br />" + Tools.JsonUtils.JsonSerializer(ToDynamicResult<kk>( new kk { aa = "test", bb = 789, cc = true, dd = DateTime.Now.AddDays(2) }, null)); Response.Write(json);
您可以重新构造带参数的特性或者修改injectAct对象,改成适合自己的
下面写个测试,改成表达式树最好了,先上个码
using System; using System.Linq; using System.Dynamic; using System.Reflection; using System.Linq.Expressions; using System.Collections.Generic; using System.Collections.Concurrent; namespace Tools { public class Class2Map { private static readonly ConcurrentDictionary<RuntimeTypeHandle, PropertyInfo[]> DynamicObjectProperties = new ConcurrentDictionary<RuntimeTypeHandle, PropertyInfo[]>(); private static PropertyInfo[] GetObjectProperties<T>() { var type = typeof(T); var key = type.TypeHandle; PropertyInfo[] queryPts = null; DynamicObjectProperties.TryGetValue(key, out queryPts); if (queryPts == null) { queryPts = type.GetProperties(); DynamicObjectProperties.TryAdd(key, queryPts); } return queryPts; } /// <summary> /// 单个对象映射 /// </summary> /// <typeparam name="T">类型</typeparam> /// <param name="source">实例</param> /// <param name="injectAct">map方法集</param> /// <returns>映射后的动态对象</returns> public static IDictionary<string, Object> DynamicResult<T>(T source, params MapCondition[] injectAct)//where T : ICustomMap { var queryPts = GetObjectProperties<T>(); var dynamicResult = new ExpandoObject() as IDictionary<string, Object>; foreach (var p in queryPts) { var attributes = 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; var condition = injectAct.FirstOrDefault(x => x.Orginal == _name); if (CheckChangeInfo(condition, out _tempname)) { _resultvalue = condition.fn.Invoke(_value); dynamicResult.Add(_tempname ?? _name, _resultvalue); continue; } } //var value = Convert.ChangeType(value,typeof(string)); dynamicResult.Add(_name, _resultvalue); } return dynamicResult; } /// <summary> /// 合并2个对象 /// </summary> /// <typeparam name="TSource">对象1类型</typeparam> /// <typeparam name="TTarget">对象2类型</typeparam> /// <param name="s">对象1实例</param> /// <param name="t">对象2实例</param> /// <returns>合并后的动态对象</returns> public static IDictionary<string, Object> MergerObject<TSource, TTarget>(TSource s, TTarget t) { var targetPts = GetObjectProperties<TSource>(); PropertyInfo[] mergerPts = null; var _type = t.GetType(); mergerPts = _type.Name.Contains("<>") ? _type.GetProperties() : GetObjectProperties<TTarget>(); var dynamicResult = new ExpandoObject() as IDictionary<string, Object>; foreach (var p in targetPts) { var attributes = p.GetCustomAttributes(typeof(IngoreProperty), true); if (attributes.FirstOrDefault() != null) continue; dynamicResult.Add(p.Name, p.GetValue(s, null)); } foreach (var p in mergerPts) { var attributes = p.GetCustomAttributes(typeof(IngoreProperty), true); if (attributes.FirstOrDefault() != null) continue; dynamicResult.Add(p.Name, p.GetValue(t, null)); } return dynamicResult; } /// <summary> /// 合并2个对象 /// </summary> /// <typeparam name="TSource">对象1类型</typeparam> /// <typeparam name="TTarget">对象2类型</typeparam> /// <param name="s">对象1实例</param> /// <param name="t">对象2实例</param> /// <returns>合并后的动态对象</returns> public static List<IDictionary<string, Object>> MergerListObject<TSource, TTarget>(List<TSource> s, TTarget t) { var targetPts = GetObjectProperties<TSource>(); PropertyInfo[] mergerPts = null; var _type = t.GetType(); mergerPts = _type.Name.Contains("<>") ? _type.GetProperties() : GetObjectProperties<TTarget>(); var result = new List<IDictionary<string, Object>>(); s.ForEach(x => { var dynamicResult = new ExpandoObject() as IDictionary<string, Object>; foreach (var p in targetPts) { var attributes = p.GetCustomAttributes(typeof(IngoreProperty), true); if (attributes.FirstOrDefault() != null) continue; dynamicResult.Add(p.Name, p.GetValue(x, null)); } foreach (var p in mergerPts) { var attributes = p.GetCustomAttributes(typeof(IngoreProperty), true); if (attributes.FirstOrDefault() != null) continue; dynamicResult.Add(p.Name, p.GetValue(t, null)); } result.Add(dynamicResult); }); return result; } private static bool CheckChangeInfo(MapCondition condition, out string name) { name = null; bool result = condition != null && condition.fn != null && !string.IsNullOrWhiteSpace(condition.Orginal);//&& //!string.IsNullOrWhiteSpace(condition.NewName); if (result) { var temp = condition.NewName; name = (string.IsNullOrWhiteSpace(temp) || temp.Trim().Length == 0) ? null : temp; } return result; } } }
测试一下:
List<KeyValue> kk = new List<KeyValue> { new KeyValue{key="aaa", value="111"}, new KeyValue{key="bbb", value="222"}, new KeyValue{key="ccc", value="333"}, new KeyValue{key="ddd", value="444"}, }; var result = Class2Map.MergerListObject<KeyValue, dynamic>(kk, new { p = "jon test" }); var json = JsonUtils.JsonSerializer(result); Response.Write(json);
输出如下:
[{"key":"aaa","value":"111","p":"jon test"},{"key":"bbb","value":"222","p":"jon test"},{"key":"ccc","value":"333","p":"jon test"},{"key":"ddd","value":"444","p":"jon test"}] var result = Class2Map.MergerObject<KeyValue, dynamic>( new KeyValue { key = "aaa", value = "111" }, new { p = "jon test" } ); var json = JsonUtils.JsonSerializer(result); Response.Write(json);
输出如下:
{ "key": "aaa", "value": "111", "p": "jon test" }
以上这篇c#动态类型,及动态对象的创建,合并2个对象,map实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持猪先飞。
相关文章
Java8 实现stream将对象集合list中抽取属性集合转化为map或list
这篇文章主要介绍了Java8 实现stream将对象集合list中抽取属性集合转化为map或list的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-05- 这篇文章主要介绍了java8如何用Stream查List对象某属性是否有重复的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-11
- 本篇文章主要分享了通过window.navigator来判断浏览器及其版本信息的实例代码。具有一定的参考价值,下面跟着小编一起来看下吧...2017-01-23
- 这篇文章主要介绍了R语言删除指定变量或对象的操作方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-05-06
- 这篇文章主要介绍了js如何实现浏览器打印功能,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-07-15
- 下面小编就为大家带来一篇利用JS实现点击按钮后图片自动切换的简单方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2016-10-25
- 这篇文章主要介绍了JavaScript预解析,对象的的相关资料,小编觉得这篇文章写的还不错,需要的朋友可以参考下,希望能够给你带来帮助...2021-11-10
- 作为前端,一直以来都知道HTTP劫持与XSS跨站脚本、CSRF跨站请求伪造。防御这些劫持最好的方法是从后端入手,前端能做的太少。而且由于源码的暴露,攻击者很容易绕过防御手段。但这不代表我们去了解这块的相关知识是没意义的,本文的许多方法,用在其他方面也是大有作用。...2021-05-24
- 这篇文章主要给大家介绍了关于Nest.js参数校验和自定义返回数据格式的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-28
- 那么今天我就用JavaScript代码来实现这个效果吧,那么首先介绍一下整个的思路,首先我们先将确定输入密码的位数,我的需求是5位,那么就用一个div标签包住5个input标签...2016-01-02
- 这篇文章主要为大家详细介绍了js实现上传图片及时预览的相关资料,具有一定的参考价值,感兴趣的朋友可以参考一下...2016-05-09
- 这篇文章主要为大家详细介绍了js+css实现回到顶部按钮back to top回到顶部按钮,感兴趣的小伙伴们可以参考一下...2016-03-03
JavaScript中的数组遍历forEach()与map()方法以及兼容写法介绍
下面小编就为大家带来一篇JavaScript中的数组遍历forEach()与map()方法以及兼容写法介绍。小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2016-05-20如何在Spring WebFlux的任何地方获取Request对象
这篇文章主要介绍了如何在Spring WebFlux的任何地方获取Request对象,帮助大家更好的理解和使用springboot框架,感兴趣的朋友可以了解下...2021-01-26- 这篇文章主要给大家介绍了一个关于JS正则匹配的踩坑记录,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-04-13
- 这篇文章主要介绍了如何使用JavaScript实现“无缝滚动 自动播放”轮播图效果,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-08-20
- 这篇文章主要介绍了js实现调用网络摄像头及常见错误处理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-07
- 这篇文章主要为大家详细介绍了JS实现随机生成验证码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-06
牛叉的Jquery――Jquery与DOM对象的互相转换及DOM的三种操作
只有jQuery对象才能调用jQuery类库的各种函数,同样有些dom对象的属性和方法在jQuery上也是无法调用的,不过基本上jQuery类库提供的函数包含了所有的dom操作。这就需要我们知道如何将jQuery对象和DOM的相互转换的方法。1...2015-10-30- 这篇文章主要为大家详细介绍了js实现列表按字母排序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-08-11