[讀書筆記 ]Stephens' C# Programming with Visual Studio 2010 24-Hour Trainer 第二十八章

  • 1041
  • 0

閱讀Stephens' C#教材第二十八章筆記

 

Chapter 28 Making Generic Classes.
 
本章將介紹泛型類別(Generic Classes),在十六章曾經介紹集合類別如List,在該章還提過泛型類別的優點:程式碼再利用與指定型別檢查
 
(specific type checking)。詳細資料請參考微軟網頁
 
泛型類別定義方式,以TreeNode泛型類別為例:
        class TreeNode<T>
        {
           ...
        }
 
其中<T>指的是某一種.NET平台提供的泛型型別的參數,在程式中,T型別就是建立實例後在程式碼中參數本身的型別,例如以下的變數rootNode,其
 
中TreeNode處理的型別是String。
 
TreeNode<string> rootNode = new TreeNode<string>();
 
如果需要在類別中使用到多個參數,可以用逗號隔開,例如有一個Matcher類別要處理員工(Employee)與工作(Job)的分配(assign)關係,則類別的參
 
數可以如下宣告:
        public class Matcher<T1, T2>
        {
           ...
        }
 
建立實例的語法如下:
Matcher<Employee, Job> jobAssigner = new Matcher<Employee, Job>();
 
由於個人目前對於泛型的認知有限,所以摘錄一些原文,以便日後有體悟後再來理解
Using Generic Constraints
To use as generic constraint, follow the noremal class declaration with the keyword where, the name of the type parameter that you want to constrain, a colon, and the constraint. Some typical conconstraint include:
  • A class from which the type must inherit
  • An interface (or interfaces) that the type must implement
  • new() to indicate that the type must provide a parameterless constructor
  • struct to inficate that the type must be a value type such as the built-in value types(int, bool) or a structure
  • class to indicate that the type must be a reference type
Separate multiple constraints for the same type parameter with commas.
if you want to constrain more than one type parameter, place a new where clause on a new line.
For example, the following code defines the generic Matcher class, whick takes two generic type parameter T1 and T2.
 
    // This version demonstrates some constraints.
    public class Matcher<T1, T2>
        where T1 : IComparable<T2>, new()
        where T2 : new()
    {
        private void test()
        {
            T1 t1 = new T1();
            T2 t2 = new T2();
            if (t1.CompareTo(t2) < 0)
            {
                // t1 is "less than" t2.
            }
        }
    }
 
The first constraint requires that type parameter T1 implement the IComparable interface for the type T2 so the code can compare T1 objects to T2 objects. The next constraint requires that the T1 type also provide a parameterless constructor. You can see that the code creates a new T1 object and uses its CompareTo method(which defined by IComparable).
The seond where clause requires that the type T2 also provide a parameterless constructor. The code needs that because it also creates a new T2 instance.
In general you should use as few constraints as possible because that makes your class usable in as many circumstances as possible. If your code won't need to create new instances of a data type, don't use the new constraint. If your code won't need to compare objects, don't use the ICompareable constraint.
 
建立泛型方法
除了建立泛型類別,你也可以在泛行類別或一般非泛型類別中建立泛型方法。
舉例來說,假如你要重新安排一個list中的項目,可以用交替取頭尾的方式重新排列,原來list中的內容為1,2,3,4,5,6,然後要重新排成
 
1,6,2,5,3,4
以下為Alternate的方法
    public List<T> Alternates<T>(List<T> list)
    {        
        //Make a new list to hold the results.
        List<T> newList = new List<T>();
        ...
        return newList;
    }
 
Alternate方法使用了泛型參數T,It takes as a reqular parameter a List that holds items of type T and it returns a new List containing items of type T.
 
以下是這個方法的使用
List<string> strings = new List<string>(stringTextBox.Text.Split(''));
List<string> alternatedStrings = Alternate<string>(string);
alternatedStringsTextBox.Text = string.Join(" ", alternatedStrings);
 
Generic methods can be quite useful for the same reasons that generic classes are. They allow code reuse without the extra hassle of converting values to and from the non-specific object class. They also perform type checking, so in this example, the program cannot try to alternate a List<int> by calling Alternate<string>.
 
TRY IT中以Randomizer程式示範如何撰寫泛型類別進行亂數排序的過程