認識C#2.0的新功能

資策會數位教育研究所講師曹山

 

 

Introduction

C#2.0可以用泛型,遞迭器,部份型態,不具名方法來建立更易軟體再用,更高效能,暨更容易維護的程式。s

泛型
為什麼要使用 泛型 ?

設計一些集合型態來做為收集特定型態的資訊往往面臨:為了要能收集不同型態的資訊則要為每一種要收集的型態創造一個集合型態的類別。例如:

class MyIntCollect {

    public  int [ ] xv = new int [ 100 ];

}

class MyBoolCollect {

    public  bool  [ ] xv = new bool [ 100 ];

}

當然, 使用像祖先級的參考型態及boxing/unboxing可解決這個問題.
但若造成您所不願看到的混雜型態的資訊的集合,我們可使用C#2.0中的泛型來建立強制型態集合。

class Employees<T> where T : Employee {

    internal Hashtable kv = new Hashtable ();

    public void Add (string empID, T emp ) {

        kv.Add(empID, emp);

   }
}

   Employees<Employee>  emps  =  new Employees<Employee>();
   emps.Add("a666666666", new Employee("a666666666"));
   emps.Add("a333333333", new Employee("a333333333"));

主要是擷取泛型的兩項優點:一是在運用泛型式來產生特定型態時可再決定像是上例中T的型態、一是可用像是上例來限制T的型態。
另外帶來的好處是避免執行時期型態的檢查及原本可能需要的boxing/unboxing的避免,如此更可提升程式的執行效率。

運用遞迭器,暨 yield 關鍵字來簡化程式開發
為什麼要運用遞迭器 ?

因為可以如下得好巡迴一個集合
foreach (Employee  em  in  emps.GetEmployees()  )  {

}

在C#2.0之下, 我們可用yield關鍵字來製作

public IEnumerable  GetEmployees() {
    foreach (Employee em in kv.Values) {
       yield return em;
    }
}

運用不具名方法
為什麼要運用不具名方法?

如此可以省略一些C#編輯器幫您產生程式碼的撰寫,而專注於企業邏輯的寫作。

private void myHandler(object mySender, EventArgs myE) {

     ...

}
button1.Click   +=   new    EventHandler( myHandler  );

運用不具名方法來藉者模組化程式片斷成為delegate方法的實例,來簡化程式開發,即可善用片斷程式成為回呼方法

運用不具名方法, 可簡化成如下:

button1.Click   +=   delegate(object    mySender,   EventArgs   myE) {

  ......

};

Nullable data type

使用Nullable可以用來做出資料庫某欄位沒有指定值的相當概念。

例如

Nullable<int>   age = null;

可用來表示某客戶的年齡不詳

Partial Types

運用Partial Types來藉者分化某一型態到不同程式檔的程式片斷中成為同一型態的程式一部份,以便多人可針對某一型態程式同步開發,即可善用此Partial Types方法。

public partial class MyPatient {

    int kindOfIllness;

    public  void getTreatment () {

    }

}

public partial class MyPatient {

   int insuranceID;

    public void  getReimbursement () {

    }
}

Static   class

靜態類別是通常為了收集一些相關的靜態方法或靜態資料的類別,如下所示:

public static class MyMath {

   public static int getMaxFromInt() {

        return maxOfInt;
   }

     private static int maxOfInt = int.MaxValue;
}

注意: 靜態類別中不可有物件方法或物件資料, 我們也不可用其來宣告為任何資料的型態。

Differentiated accessibility of getter and setter of property

運用屬性的getter及setter的設定成不同的存取權限,以便藉此方法,即可來做出一些企業權限控管的邏輯。例如:  類別的設計人員可以使用setter,但任何程式皆可使用getter。

public  class SavingsAccount {

      decimal  balance;

       public  decimal Balance {

            get { return this.balance; }

            private set {

                 if ( value < 0 ) return;

                  balance = value;         

             }

       }

       public void Withdraw ( decimal  amount ) {

            this.Balance   = this.Balance   -   amount;

       }

}

External Aliases

運用C#2.0的external aliases的設定可以將原會發生名稱衝突的相同名稱的資料型態用在同一程式中。例如:  有人設計好一個類別的資料型態全名為MediCare.Patient(假設其存放於MediCareOfTaiwan.dll),而另一個設計好的類別的全名也為MediCare.Patient(假設其存放於MediCareOfUSA.dll),則在同下述程式(存到檔案名為program.cs)中無法區分要使用的是前者或是後者。所以此程式是不能成功地建置。

class Program {

  static void Main(string[] args) {

    Patient taiwanPat = new Patient();

    Patient usaPat      = new Patient();

  }

}

我們把上述程式修改如下:

extern alias Taiwan;

extern alias USA;

class Program {

  static void Main(string[] args) {

    Taiwan.MediCare.Patient taiwanPat = new Taiwan.MediCare.Patient();

    USA.MediCare.Patient usaPat = new USA.MediCare.Patient();

  }

}

再用下述方式編譯:

csc    /r:Taiwan=MediCareOfTaiwan.dll  /r:USA=MediCareOfUSA.dll    program.cs

則可成功地建置,如此還是能在同一程式中區分前者要使用的是MediCareOfTaiwan.dll 而後者要使用的是MediCareOfUSA.dll 中的MediCare.Patient的資料型態。


Summary

用泛型,我們可以建立更有效率且強健的容器型的資料型態。

運用yield關鍵字可以很容易來製作遞迭器,而有了遞迭器,我們可以讓使用者方便地用foreach巡迴一個集合。

運用部份型態,可以方便地進行同一資料型態的團隊同時開發。

使用不具名方法,可以簡化事件方法的登記程式碼。

運用靜態類別,可以更明確得來包含靜態的方法和靜態的資料。

利用屬性的存取的可見度等級的差異,可以滿足設計屬性存取的不見得要可見度一致的特性。

運用C#2.0的external aliases的設定,可以化解相同名稱的資料型態發生名稱衝突的狀況。


從 C#2.0開始,我們多了以上這些功能來建立更易軟體再用,更高效能,暨更容易維護的程式。如此寫更少程式碼,但同時卻提升程式設計者的生產力