经常会碰到如许的状况,我们在相应客户端要求的数据的时刻须要对数据举行处置惩罚,比方数据库中的数据是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实例代码的细致内容,更多请关注ki4网别的相干文章!