欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C# 反射(Reflection)的用處分析

 更新時間:2015年03月25日 09:08:12   投稿:hebedich  
反射(Reflection)是C#里很重要的一個特性,其它語言也有這個特性,比如JAVA。反射這個特性是很實用的,如果使用過struts, hibernate, spring等等這些框架的話,便會知道反射這個特性是多么的強(qiáng)大了。在我接觸過的那些框架中,沒有一個框架是不使用反射的。

亂侃

       作為一名新手,一直沒有勇氣去寫一篇分享。原因有很多:諸如:自己水平有限、語言表達(dá)不準(zhǔn)確、寫出的東西沒有一點技術(shù)點被人嘲笑。今天在公司聽了內(nèi)部員工的一個分享,其中最重要的一點是:提升自身水平的最佳的途徑就是——交流。不管你是通過什么途徑,交流也好、整理成文字分享也好等等都是很好的方式。故此,今天獻(xiàn)丑寫一篇自己的心得分享,歡迎各路大神的指教!

   需求背景

     今天接到的需求里面有個這樣的需求,如下圖所示,需要打印出如Excel內(nèi)容呈現(xiàn)的單據(jù)。

    動手操作第一版本

     而為了實現(xiàn)這個業(yè)務(wù)需要涉及三張表的數(shù)據(jù)。(存放單據(jù)的表、審核意見表、審核狀態(tài)表)
     三張表的關(guān)系:單據(jù)表1:1審核狀態(tài)表,單據(jù)表1:N審核意見表
     為了實現(xiàn)讓View頁面整潔,我定義了一個SpecialPrintModel類

public class SpecialPrintModel
  {
    /// <summary>
    /// 供應(yīng)商承擔(dān)
    /// </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>
    /// 經(jīng)辦人
    /// </summary>
    public string ResponseiblePerson { get; set; }

    /// <summary>
    /// 分管領(lǐng)導(dǎo)
    /// </summary>
    public string Leader { get; set; }

    /// <summary>
    /// 財務(wù)審核
    /// </summary>
    public string FinanceApproval { get; set; }

    /// <summary>
    /// 財務(wù)經(jīng)理審核
    /// </summary>
    public string FinanceManagerApproval { get; set; }

    /// <summary>
    /// 財務(wù)總監(jiān)審核
    /// </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);//查找出待支付的單據(jù)表信息
   ArrayList serialArray=new ArrayList();//定義一個流水號列表
   toBePaidModel.ForEach((u) => { serialArr.Add(u.SerialNumber); });
   var toBePaidComment = persistant.GetTobePaidRecepitComment(serialArr);//查找出待支付單據(jù)的審核意見表(1個單據(jù)對應(yīng)多少審核意見)
   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
 }

    呵呵,上面的代碼基本完成了業(yè)務(wù)的需求,可是如果業(yè)務(wù)需要打印出CTO的名稱、CIO的名稱那在if else這邊加,雖然很簡單但是違背了開放-封閉的原則。故本人決定用反射去完成這if...else的事情。
因為if...else里面的判斷是當(dāng)前的這筆單據(jù)的審核意見表的層級是不是跟SpecialPrintModel的字段所對應(yīng)的層級相等,若相等則在對應(yīng)字段寫入相對應(yīng)的名稱。決定把SpecialPrintModel這個類修改下。
 
   動手操作第二版本

public class ShipSpecialPrintModel
  {
    /// <summary>
    /// 供應(yīng)商承擔(dān)
    /// </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>
    /// 經(jīng)辦人
    /// </summary>
    public string ResponseiblePerson { get; set; }

    /// <summary>
    /// 分管領(lǐng)導(dǎo)
    /// </summary>
    [LevelAttribute(Level = 1)]
    public string Leader { get; set; }

    /// <summary>
    /// 財務(wù)審核
    /// </summary>
     [LevelAttribute(Level = 2)]
    public string FinanceApproval { get; set; }

    /// <summary>
    /// 財務(wù)經(jīng)理審核
    /// </summary>
     [LevelAttribute(Level = 3)]
    public string FinanceManagerApproval { get; set; }

    /// <summary>
    /// 財務(wù)總監(jiān)審核
    /// </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那邊基本上每循環(huán)一次都需要去反射查找下元素,為了避免這樣的性能消耗,決定再修改一翻,定義一個字典去存儲SpecialPrintModel標(biāo)有特性類的字段。

   動手操作第三版本

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);
              }
          });

   總體經(jīng)過三次的修改,已經(jīng)避免if...else的代碼。這樣而言,也比較適合后面比如再需要打印CTO審核的名稱。那樣只需要再Model類里面填寫字段與在字段上加上個特效。

  總結(jié)

      就像我同事說的那樣,做任務(wù)事情只要想想、多敲幾次。一些問題就不是問題了。好了,今天就寫到這里吧。晚安各位!

請您花一點時間將文章分享給您的朋友或者留下評論。我們將會由衷感謝您的支持!

相關(guān)文章

  • C#利用TreeView控件實現(xiàn)目錄跳轉(zhuǎn)

    C#利用TreeView控件實現(xiàn)目錄跳轉(zhuǎn)

    這篇文章主要為大家詳細(xì)介紹了C#潤滑利用TreeView控件實現(xiàn)目錄跳轉(zhuǎn)功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以動手嘗試一下
    2022-07-07
  • C#?崩潰異常中研究頁堆布局的詳細(xì)過程

    C#?崩潰異常中研究頁堆布局的詳細(xì)過程

    最近遇到一位朋友的程序崩潰,發(fā)現(xiàn)崩潰點在富編輯器 msftedit 上,這個不是重點,重點在于發(fā)現(xiàn)他已經(jīng)開啟了 頁堆,由于 頁堆 和 NT堆 的內(nèi)存布局完全不一樣,這一篇結(jié)合我的了解以及 windbg 驗證來系統(tǒng)的介紹下 頁堆,需要的朋友可以參考下
    2022-10-10
  • Unity多語言轉(zhuǎn)換工具的實現(xiàn)

    Unity多語言轉(zhuǎn)換工具的實現(xiàn)

    這篇文章主要為大家詳細(xì)介紹了Unity多語言轉(zhuǎn)換工具的實現(xiàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • C#程序中創(chuàng)建、復(fù)制、移動、刪除文件或文件夾的示例

    C#程序中創(chuàng)建、復(fù)制、移動、刪除文件或文件夾的示例

    這篇文章主要介紹了C#程序中創(chuàng)建、復(fù)制、移動、刪除文件或文件夾的示例,即對System.IO命名空間中類的運用,需要的朋友可以參考下
    2016-02-02
  • Oracle中for循環(huán)的使用方法

    Oracle中for循環(huán)的使用方法

    這篇文章介紹了Oracle中for循環(huán)的使用方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-08-08
  • [C#].NET中幾種Timer的使用實例

    [C#].NET中幾種Timer的使用實例

    本篇文章主要介紹了.NET中幾種Timer的使用,具有一定的參考價值,有興趣的可以了解一下。
    2016-12-12
  • C#實現(xiàn)Ruby的負(fù)數(shù)索引器

    C#實現(xiàn)Ruby的負(fù)數(shù)索引器

    這篇文章主要介紹了C#實現(xiàn)Ruby的負(fù)數(shù)索引器的相關(guān)代碼和使用方法,非常簡單實用,需要的朋友可以參考下
    2016-07-07
  • C#實現(xiàn)較為實用的SQLhelper

    C#實現(xiàn)較為實用的SQLhelper

    這篇文章主要為大家詳細(xì)介紹了C#實現(xiàn)較為實用SQLhelper的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • c# 連接池的設(shè)置與使用

    c# 連接池的設(shè)置與使用

    這篇文章主要介紹了c# 連接池的設(shè)置與使用,幫助大家更好的理解和學(xué)習(xí)c#,感興趣的朋友可以了解下
    2021-01-01
  • C#實現(xiàn)讀取DataSet數(shù)據(jù)并顯示在ListView控件中的方法

    C#實現(xiàn)讀取DataSet數(shù)據(jù)并顯示在ListView控件中的方法

    這篇文章主要介紹了C#實現(xiàn)讀取DataSet數(shù)據(jù)并顯示在ListView控件中的方法,涉及C#操作DataSet及ListView控件的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-10-10

最新評論