程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 淺談C# Reflection用處

淺談C# Reflection用處

編輯:C#入門知識

淺談C# Reflection用處


動手操作第一版本      而為了實現這個業務需要涉及三張表的數據。(存放單據的表、審核意見表、審核狀態表)      三張表的關系:單據表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類裡面填寫字段與在字段上加上個特效。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved