c#動(dòng)態(tài)類型,及動(dòng)態(tài)對(duì)象的創(chuàng)建,合并2個(gè)對(duì)象,map實(shí)例
經(jīng)常會(huì)遇到這樣的情況,我們?cè)陧憫?yīng)客戶端請(qǐng)求的數(shù)據(jù)的時(shí)候需要對(duì)數(shù)據(jù)進(jìn)行處理,比如數(shù)據(jù)庫(kù)中的數(shù)據(jù)是int型,它可能表示某個(gè)枚舉,或者其它的邏輯意義(數(shù)據(jù)庫(kù)這樣的設(shè)計(jì)可能是從數(shù)據(jù)安全性、存儲(chǔ)量上等角度考慮),但是客戶端顯示的時(shí)候需要是它具體的意義。
這個(gè)時(shí)候我們的處理方式一般都是2中的,如果邏輯不復(fù)雜,且單一的話,直接修改sql語(yǔ)句就能處理好數(shù)據(jù)源,這個(gè)時(shí)候代碼里面不需要處理什么。
但是如果邏輯復(fù)稍許復(fù)雜或者判斷的情況有很多分支,我們不得不從代碼角度來(lái)處理了。單個(gè)對(duì)象還好,多個(gè)對(duì)象比如是個(gè)list<T>,那就要循環(huán)對(duì)某個(gè)對(duì)象的字段進(jìn)行XXX了。
進(jìn)而衍生出了這就出現(xiàn)了DTO,Arg的中間對(duì)象,當(dāng)然,我個(gè)人是很喜歡這樣的設(shè)計(jì)的,但是某些時(shí)候也會(huì)偷懶不想寫(xiě)(多半情況我直接寫(xiě)代碼生器批量生產(chǎn)),比如在測(cè)試的時(shí)候,在接私活的時(shí)候,在演示的時(shí)候,只為快速呈現(xiàn)想要的效果 都懶得去屑,是的,你會(huì)說(shuō)市面上不是有很多的map庫(kù),比如automap,tinymap,甚至json.net里面的動(dòng)態(tài)特性重寫(xiě),方法當(dāng)然很多,但用一個(gè)大輪子來(lái)費(fèi)力搞這么個(gè)小事,我覺(jué)得劃不來(lái)。且輪子越來(lái)越大它要干的事越多,我可不想搞的那么復(fù)雜,嗯,就是這樣,寫(xiě)了個(gè)。
具體的代碼貼到下面,如果看明白,會(huì)很方便的擴(kuò)展了或修改成自己想要的效果。
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> /// 支持動(dòng)態(tài)輸出的對(duì)象接口 /// </summary> public interface IInjectClass { } /// <summary> /// 動(dòng)態(tài)輸出時(shí)忽略此標(biāo)記的屬性 /// </summary> public class IngorePropertyAttribute : Attribute { }
下面我們測(cè)試一個(gè):
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);
您可以重新構(gòu)造帶參數(shù)的特性或者修改injectAct對(duì)象,改成適合自己的
下面寫(xiě)個(gè)測(cè)試,改成表達(dá)式樹(shù)最好了,先上個(gè)碼
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> /// 單個(gè)對(duì)象映射 /// </summary> /// <typeparam name="T">類型</typeparam> /// <param name="source">實(shí)例</param> /// <param name="injectAct">map方法集</param> /// <returns>映射后的動(dòng)態(tài)對(duì)象</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; //原來(lái)是屬性名 var _value = p.GetValue(source, null); //原來(lái)的屬性值 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個(gè)對(duì)象 /// </summary> /// <typeparam name="TSource">對(duì)象1類型</typeparam> /// <typeparam name="TTarget">對(duì)象2類型</typeparam> /// <param name="s">對(duì)象1實(shí)例</param> /// <param name="t">對(duì)象2實(shí)例</param> /// <returns>合并后的動(dòng)態(tài)對(duì)象</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個(gè)對(duì)象 /// </summary> /// <typeparam name="TSource">對(duì)象1類型</typeparam> /// <typeparam name="TTarget">對(duì)象2類型</typeparam> /// <param name="s">對(duì)象1實(shí)例</param> /// <param name="t">對(duì)象2實(shí)例</param> /// <returns>合并后的動(dòng)態(tài)對(duì)象</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; } } }
測(cè)試一下:
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#動(dòng)態(tài)類型,及動(dòng)態(tài)對(duì)象的創(chuàng)建,合并2個(gè)對(duì)象,map實(shí)例就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持我們。
上一篇:c# Winform 程序自動(dòng)更新實(shí)現(xiàn)方法
欄 目:C#教程
下一篇:C#中圖片.BYTE[]和base64string的轉(zhuǎn)換方法
本文標(biāo)題:c#動(dòng)態(tài)類型,及動(dòng)態(tài)對(duì)象的創(chuàng)建,合并2個(gè)對(duì)象,map實(shí)例
本文地址:http://mengdiqiu.com.cn/a1/C_jiaocheng/5887.html
您可能感興趣的文章
- 01-10C#實(shí)現(xiàn)主窗體最小化后出現(xiàn)懸浮框及雙擊懸浮框恢復(fù)原窗體的方
- 01-10C#動(dòng)態(tài)創(chuàng)建button的方法
- 01-10C#動(dòng)態(tài)創(chuàng)建Access數(shù)據(jù)庫(kù)及密碼的方法
- 01-10C#路徑,文件,目錄及IO常見(jiàn)操作匯總
- 01-10C#禁止textbox復(fù)制、粘貼、剪切及鼠標(biāo)右鍵的方法
- 01-10C#及WPF獲取本機(jī)所有字體和顏色的方法
- 01-10C#獲取動(dòng)態(tài)生成的CheckBox值
- 01-10C#中DataGridView動(dòng)態(tài)添加行及添加列的方法
- 01-10winform實(shí)現(xiàn)限制及解除鼠標(biāo)移動(dòng)范圍的方法
- 01-10C#實(shí)現(xiàn)HTML轉(zhuǎn)WORD及WORD轉(zhuǎn)PDF的方法


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 01-10C#通過(guò)反射獲取當(dāng)前工程中所有窗體并
- 01-10關(guān)于ASP網(wǎng)頁(yè)無(wú)法打開(kāi)的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實(shí)現(xiàn)txt定位指定行完整實(shí)例
- 01-10WinForm實(shí)現(xiàn)仿視頻播放器左下角滾動(dòng)新
- 01-10C#停止線程的方法
- 01-10C#實(shí)現(xiàn)清空回收站的方法
- 01-10C#通過(guò)重寫(xiě)Panel改變邊框顏色與寬度的
- 01-10C#實(shí)現(xiàn)讀取注冊(cè)表監(jiān)控當(dāng)前操作系統(tǒng)已
隨機(jī)閱讀
- 04-02jquery與jsp,用jquery
- 01-10C#中split用法實(shí)例總結(jié)
- 01-10delphi制作wav文件的方法
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-11Mac OSX 打開(kāi)原生自帶讀寫(xiě)NTFS功能(圖文
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載