C# 反射(Reflection)的用途剖析。本站提示廣大學習愛好者:(C# 反射(Reflection)的用途剖析)文章只能為提供參考,不一定能成為您想要的結果。以下是C# 反射(Reflection)的用途剖析正文
亂侃
作為一位老手,一向沒有勇氣去寫一篇分享。緣由有許多:諸如:本身程度無限、說話表達禁絕確、寫出的器械沒有一點技巧點被人譏笑。明天在公司聽了外部員工的一個分享,個中最主要的一點是:晉升本身程度的最好的門路就是——交換。不論你是經由過程甚麼門路,交換也好、整頓成文字分享也好等等都是很好的方法。故此,明天獻丑寫一篇本身的心得分享,迎接各路年夜神的指教!
需求配景
明天接到的需求外面有個如許的需求,以下圖所示,須要打印出如Excel內容出現的單據。
著手操作初版本
而為了完成這個營業須要觸及三張表的數據。(寄存單據的表、審核看法表、審核狀況表)
三張表的關系:單據表1:1審核狀況表,單據表1:N審核看法表
為了完成讓View頁面整潔,我界說了一個SpecialPrintModel類
public class SpecialPrintModel { /// <summary> /// 供給商承當 /// </summary> public string SupplierUnderTaker { get; set; } /// <summary> /// 客戶定單號 /// </summary> public string CustomerSerialNumber { get; set; } /// <summary> /// 付款金額 /// </summary> public decimal PayAmount { get; set; } /// <summary> /// 開戶行 /// </summary> public string OpeningBank { get; set; } /// <summary> /// 收款單元 /// </summary> public string CollectionMonad { get; set; } /// <summary> /// 銀行帳號 /// </summary> public string BankAccount { get; set; } /// <summary> /// 經辦人 /// </summary> public string ResponseiblePerson { get; set; } /// <summary> /// 分擔引導 /// </summary> public string Leader { get; set; } /// <summary> /// 財政審核 /// </summary> public string FinanceApproval { get; set; } /// <summary> /// 財政司理審核 /// </summary> public string FinanceManagerApproval { get; set; } /// <summary> /// 財政總監審核 /// </summary> public string FinanceDirectorApproval { get; set; } /// <summary> /// CEO審核 /// </summary> public string CEOApproval { get; set; } /// <summary> /// 流水號 /// </summary> public string SerialNumber { get; set; } }
public List<ShipSpecialPrintModel> GetTobePaidRecepit(ShipSpecialSearch search) { List<ShipSpecialPrintModel> curiseShipModel = new List<ShipSpecialPrintModel>(); var toBePaidModel = persistant.GetTobePaidRecepit(search);//查找出待付出的單據表信息 ArrayList serialArray=new ArrayList();//界說一個流水號列表 toBePaidModel.ForEach((u) => { serialArr.Add(u.SerialNumber); }); var toBePaidComment = persistant.GetTobePaidRecepitComment(serialArr);//查找出待付出單據的審核看法表(1個單據對應若干審核看法) foreach (var item in toBePaidModel) { ShipSpecialPrintModel temp = new ShipSpecialPrintModel() { SupplierUnderTaker = supplierUnderTaker; CustomerSerialNumber = item.CustomerOrderNumber; PayAmount = item.PayAmount; OpeningBank = item.PayBank; CollectionMonad = item.Payee; ResponseiblePerson = item.Creator; SerialNumber = item.SerialNumber; }; curiseShipModel.Add(temp); } foreach (var curise in curiseShipModel) { foreach (var comment in toBePaidComment) { if (comment.SerialNumber == curise.SerialNumber) { if (comment.ApprovalLevel == (int)LevelType.BranchedLeader) { curise.Leader = comment.Creator; } else if (comment.ApprovalLevel == (int)LevelType.Finance) { curise.FinanceApproval = comment.Creator; } else if (comment.ApprovalLevel == (int)LevelType.FinanceManager) { curise.FinanceManagerApproval = comment.Creator; } else if (comment.ApprovalLevel == (int)LevelType.ProjectDirector) { curise.FinanceDirectorApproval = comment.Creator; } else if (comment.ApprovalLevel == (int)LevelType.CEO) { curise.CEOApproval = comment.Creator; } } } } return curiseShipModel }
呵呵,下面的代碼根本完成了營業的需求,可是假如營業須要打印出CTO的稱號、CIO的稱號那在if else這邊加,固然很簡略然則違反了開放-關閉的准繩。故自己決議用反射去完成這if...else的工作。
由於if...else外面的斷定是以後的這筆單據的審核看法表的層級是否是跟SpecialPrintModel的字段所對應的層級相等,若相等則在對應字段寫入絕對應的稱號。決議把SpecialPrintModel這個類修正下。
著手操作第二版本
public class ShipSpecialPrintModel { /// <summary> /// 供給商承當 /// </summary> public string SupplierUnderTaker { get; set; } /// <summary> /// 客戶定單號 /// </summary> public string CustomerSerialNumber { get; set; } /// <summary> /// 付款金額 /// </summary> public decimal PayAmount { get; set; } /// <summary> /// 開戶行 /// </summary> public string OpeningBank { get; set; } /// <summary> /// 收款單元 /// </summary> public string CollectionMonad { get; set; } /// <summary> /// 銀行帳號 /// </summary> public string BankAccount { get; set; } /// <summary> /// 經辦人 /// </summary> public string ResponseiblePerson { get; set; } /// <summary> /// 分擔引導 /// </summary> [LevelAttribute(Level = 1)] public string Leader { get; set; } /// <summary> /// 財政審核 /// </summary> [LevelAttribute(Level = 2)] public string FinanceApproval { get; set; } /// <summary> /// 財政司理審核 /// </summary> [LevelAttribute(Level = 3)] public string FinanceManagerApproval { get; set; } /// <summary> /// 財政總監審核 /// </summary> [LevelAttribute(Level = 4)] public string FinanceDirectorApproval { get; set; } /// <summary> /// CEO審核 /// </summary> [LevelAttribute(Level = 5)] public string CEOApproval { get; set; } /// <summary> /// 流水號 /// </summary> public string SerialNumber { get; set; } } public class LevelAttribute : Attribute { public int Level { get; set; } }
var toBePaidComment = persistant.GetTobePaidRecepitComment(ArrayList.Adapter(toBePaidModel.Select(u => u.SerialNumber).ToList())); var specialPropertyInfo = (from property in typeof(CuriseShipSpecialPrintModel).GetProperties() where property.GetCustomAttributes(typeof(LevelAttribute), false).Count() > 0 select property).ToList(); toBePaidModel.ForEach((item)=>{ ShipSpecialPrintModel temp = new ShipSpecialPrintModel() { SupplierUnderTaker = supplierUnderTaker; CustomerSerialNumber = item.CustomerOrderNumber; PayAmount = item.PayAmount; OpeningBank = item.PayBank; CollectionMonad = item.Payee; ResponseiblePerson = item.Creator; SerialNumber = item.SerialNumber; }; var thisComments=toBePaidComment.Where(u=>u.SerialNumber =item.SerialNumber ).ToList(); thisComment.ForEach((cm)=> { if(cm.ApprovalLevel==(specialPropertyInfo.GetCustomAttributes(typeof(LevelAttribute),false).First() as LevelAttribute).Level) { cm.SetValue(model,cm.Creator,null); } }); })
但是看到,propertyInfos那裡根本上每輪回一次都須要去反射查找下元素,為了不如許的機能消費,決議再修正一翻,界說一個字典去存儲SpecialPrintModel標有特征類的字段。
著手操作第三版本
Dictionary<int, PropertyInfo> dic = new Dictionary<int, PropertyInfo>(); propertyInfos.ForEach((myProperty) => { dic.Add((a.GetCustomAttributes(typeof(LevelAttribute),false).First() as LevelAttribute).Level,myProperty)); } ); comments.ForEach((cm) => { if (dic.Keys.Contains(cm.ApprovalLevel)) { dic[cm.ApprovalLevel].SetValue(model, cm.Creator, null); } });
整體經由三次的修正,曾經防止if...else的代碼。如許而言,也比擬合適前面好比再須要打印CTO審核的稱號。那樣只須要再Model類外面填寫字段與在字段上加上個殊效。
總結
就像我同事說的那樣,做義務工作只需想一想、多敲幾回。一些成績就不是成績了。好了,明天就寫到這裡吧。晚安列位!
請您花一點時光將文章分享給您的同伙或許留下評論。我們將會由衷感激您的支撐!