iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 25
1
Software Development

我要轉職成 C# / .NET 工程師系列 第 25

集合之 ArrayList的醜、泛型List<T>的好

  • 分享至 

  • xImage
  •  

泛型是C#2.0搭配.NET Framework 2.0推出的東西,泛型是一種模板,將型別傳入模板,讓我們產生對應型別的類別、方法或變數等等,減少只是因為型別不同而重複的程式碼。另外.NET Framework 2.0推出的泛型集合List<T>類別,可以讓我們快速製作自訂類別的集合,減少C#1.0自訂類別集合製作方式的效能問題與除錯困難的問題。今天會講ArrayList與List<T>,明天講泛型。

集合(Collections)

集合(Collections)是一群不確定數量的類別聚集起來稱為集合,相對地如果是一群確定數量的類別那稱為陣列(array),一個集合物件裡面類別物件數量可以增加或減少,一個陣列物件裡面的類別數量在new出來就已經決定。

例如:報名人數列表,我們可能就會用集合來作而不是陣列,畢竟陣列建立出來後就是固定大小固定數量的,如果一張表上陣列格數20格,當報名人數超過20人時,陣列的作法是拿新的表劃出30格或40格陣列,再把舊表的20格複製到新表上去,其實很麻煩也有記憶體上的效能問題。這種例子改用集合作就非常好,可以動態的增加格子數,也不用重新產生新的表。

.NET Framework1.0最早在命名空間System.Collections中提供多種集合類別,並於2.0時新增System.Collections.Generic命名空間提供多種實用非常多的泛型集合。

C# 1.0 糟糕的 ArrayList

我們自訂的類別要做集合,在C# 1.0我們會用.NET類別庫的ArrayList來作,使用上比較繁瑣外,問題還很多。當2.0出現泛型集合List<T>之後,C#工程師就像是獲得救贖。(所以現在不要再用ArrayList)
我們說C#中所有東西都是物件、都是繼承自System.Object,所以如果要作不確定數量的物件集合,ArrayList都把所由類別物件都轉型成object存起來,在取出時才轉型成我們要得類別物件。除了存取上頻繁的轉型耗能外,執行時轉型錯誤的情況常常不是編譯器能事前發現的。

例如我們有一個會員列表,程式碼如下:

public class 會員
{
    public string 會員ID { get; set; }
    public string 名稱 { get; set; }
}

https://ithelp.ithome.com.tw/upload/images/20191011/20120420A0Ws14JQo8.png

如果寫錯轉型的型別,C#編譯器檢查時並不會發現,如果集合中物件數量很多,便會每次多取都要進行轉型而降低效能。如果怕每次操作這個會員列表時都要寫一次轉型,可以是用先前講的索引函式,如下:

public class 會員名冊
{
    private ArrayList 名冊 = new ArrayList();

    public void Add(會員 人)
    {
        名冊.Add(人);
    }

    public 會員 this [int index]
    {
        get
        {
            if (index >= 0 && index < 名冊.Count)
            {
                return (會員)名冊[index];
            }
            else
            {
                return null;
            }
        }
        set
        {
            if (index >= 0 && index < 名冊.Count)
            {
                 名冊[index] = value;
            }
            if(index == 名冊.Count)
            {
                名冊.Add(value);
            }                    
        }                
    }
}      

可以看到我們的會員人會轉成object
https://ithelp.ithome.com.tw/upload/images/20191011/20120420fjJKlmYXiN.png

使用時就不用再寫轉型型別:
https://ithelp.ithome.com.tw/upload/images/20191011/20120420bEkFz4vX89.png

但這樣寫起來很麻煩,而且該天若要作員工名冊、廠商名冊等相似的內容,不是要一值複製貼上嗎?如果要更改名冊的程式碼不就要一個一個找?在C#2.0List<T>出現了。

C# 2.0 美好的 List<T>

List<T>是.NET Framework2類別庫提供的泛型集合,將<>號裡面的T改成我們指定的型別,就會產生對應型別的集合,存入取出的過程都會是我們指定的型別,而不用每次都轉換成object影響到效能,編譯器也會知道我們指定成什麼型別,幫我們正確的進行型別檢查,免得執行時才發現選錯型別。另外透過List<T>這一份模板可以幫我們省略掉剛剛撰寫ArrayList索引函式,也不用因為員工名冊、廠商名冊的出現而複製成多份的程式碼。
https://ithelp.ithome.com.tw/upload/images/20191012/20120420LGta3BMETJ.png

透過替換其他型別,就能產生對於廠商、員工的程式碼。快速又簡單。
https://ithelp.ithome.com.tw/upload/images/20191012/20120420W07J2byu2q.png


上一篇
C#的var、dynamic、const、readonly
下一篇
泛型-實作泛型方法
系列文
我要轉職成 C# / .NET 工程師34
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言