標籤:

說說C#中IList與List區別?

他們的區別?

IList & IList11 =new List &();

List & List11 =new List &();
以及使用場景?


@張曉華和 @Pinwheel 基本都闡述清楚了,我來補充一下。

IList是介面無疑,屬於命名空間:System.Collections下,我們來看一下IList的定義:

[ComVisibleAttribute(true)]
public interface IList : ICollection, IEnumerable

從繼承關係中我們可以看出,IList繼承了集合和枚舉(迭代)器介面,介面的定義我們沒有什麼可看的,定義就是定義。以下引用MSDN的描述(蓋茨應該不會告我侵權吧)

IList 泛型介面是 ICollection 介面的子代,並且是所有非泛型列表的基介面。 IList 實現有三種類別:只讀、固定大小、可變大小。無法修改只讀IList。固定大小的 IList 不允許添加或移除元素,但允許修改現有元素。可變大小的 IList 允許添加、移除和修改元素。

有關此介面的泛型版本,請參見 System.Collections.Generic.IList&

從上面的描述我們知道,IList是是所有非泛型列表的基介面並且還有一個泛型版本,等一下我們和List&一起講。

--------------------------------------------啦啦啦-------------我來分隔啦---------------------------------------------

現在來說一下List&類,這個類了不得,想當年哥還在苦心鑽研.net 1.0的時候,微軟突然放了這麼一個大招,確實把我給打暈了。實際上List&是.net framework 2.0時代的產物,泛型的出現,改變了一切!本來我已經往Java的路上邁了一大步了,活生生的被泛型給吸引回來了,想當年也是用Enterprise開發過商業項目的人啊!

說了一堆廢話,接著膜拜List&,還是老樣子,看看List&類的定義:

[SerializableAttribute]
public class List& : IList&, ICollection&,
IEnumerable&, IList, ICollection, IEnumerable

這貨來自: System.Collections.Generic命名空間!!!首先是實現了IList&、 ICollection&、IEnumerable&的泛型版本,然後再實現了上面3個介面的常規版本。發現什麼問題了嗎?

問題就是既然有了泛型版本,還要常規版本作甚!這就是微軟一貫的向前兼容作風的真實體現!用泛型的好處是免去了裝箱和拆箱之苦(然而並沒有),微軟說:童話里都是騙人的,世界上根本沒有這種事!就是我給丫的吃了顆棒棒糖而已,現在是,過去是,將來還是,.net開發人員已哭暈在廁所!

由於List對於1.0來說過去強大,我就不細說了,看鏈接:List(T) 類 (System.Collections.Generic) ,如果你現在是直接上手.net4.0,當我沒說,自從3.5時代推出擴展方法後,泛型類型日益強大,現在已經沒人記得ArrayList,Hashtable,BitArray,Queue,Stack是幹什麼用的了,微軟沒擴展到的,自己寫一個,so easy!媽媽再也不用擔心我的代碼不好看!

對了,List的擴展方法都在System.Linq命名空間裡面,我無聊數了一下,有4000行代碼,大家有空可以慢慢學習,鏈接奉上:System.Linq 命名空間 ()。

最後說一下使用場景:

IList:當你建立一個方法,希望可以接收不同類型的參數時,建議用介面,當然你得考慮內部的邏輯是不是可以通過介面解決,如果還要進行數據分析或者別的什麼,就是介面滿足不了的時候,還是老老實實的用會具體的參數。

List&這貨的好處我在上面已經說了,做方法返回值我認為很合適,因為要對結果進行迭代、分析、查詢等等,它都能滿足你,還不用你轉來轉去,為了裝箱拆箱把代碼弄得烏煙瘴氣的!

暫時說這麼多吧,如果有不對的地方,你打我呀。


List是一個類(Class)。

List& myFuckList = List&();

變數 myFuckList 是一個List&類型的變數, 可以接受任意繼承自List&類的類。比如你可以自己實現一個 TheFuckingList&類,繼承自List&。都可以賦值給myFuckList。

IList是一個介面(Interface)。

IList& myFuckIList = List&();

變數 myFuckIList 是一個IList&類型的變數, 可以接受任意實現了IList&介面的類。比如你可以自己實現一個 TheFuckingIList& 類, 實現了 IList&介面就行。都可以賦值給myFuckIList。


List一般是直接拿來用的。

IList是List無法滿足你的時候,自己實現一下拿來用的。比如list的sort方法,一般的只支持系統內置類型的排序(int)。如果需要對list中的「姓名」來排序,比如張三,李四。按照筆畫還是拼音就要靠你實現了。

其他集合類型同理。

我也是小白,看《.NET之美》好像說過這一點。大神請糾正…


// 介面 A, 包含方法: Func_A()
interface A
{
void Func_A();
}

// 介面 B, 包含方法: Func_B()
interface B
{
void Func_B();
}

// 類 Test,實現介面 A、B, 即實現方法: Func_A()、Func_B()
class Test : A, B
{
public void Func_A()
{
Console.WriteLine("implement A");
}

public void Func_B()
{
Console.WriteLine("implement B");
}
}

Test t1 = new Test(); // 創建一個 Test 類型的 Test 對象,該對象基於了 Test 實現的所有介面,即 A、B
t1.Func_A(); // 可調用 Func_A(), 這是對介面 A 的實現
t1.Func_B(); // 也可調用 Func_B(), 這是對介面 B 的實現

A t2 = new Test(); // 創建一個 A 類型的 Test 對象,該對象只基於介面 A
t2.Func_A(); // 因此只能調用對介面 A 的實現方法:Func_A(), 不能調用 Func_B()

B t3 = new Test(); // 創建基於介面 B 的 Test 對象
t2.Func_B(); // 同理只能調用 Func_B(), 不能調用 Func_A()

類似地,由於 List 是一個實現了包括 IList、IReadOnlyList、IReadOnlyCollection 等多個介面的類,相應地,也就實現了這些介面中包含的所有方法。

List& list = new List&();

當你定義了一個 List 類型的對象時,也就獲取了 List 類實現的所有介面的方法;

IList& _list = new List&();

而當定義的對象是 IList 類型時,表明該對象只基於介面 IList,也就只能調用 IList 介面中定義的方法(當然包括 IList 本身實現的其它介面的方法)。換句話說,當你只需要使用 IList 介面中規定的方法時,由於不獲取 List 類實現的其他介面的方法,這樣的定義有效地節省了空間。

以上拙見,說得較淺顯,請多指教。如有錯誤,歡迎指正。


List是一個泛型類,你可以理解成一個鏈表,而IList是一個介面,List類型實現了IList介面。你可以實例化類卻不可以實例化介面。


推薦閱讀:

WPF繪製圖表時,1ms更新一次數據,界面變得特別卡?
Mono的應用廣泛嗎?
誰能介紹學習.net core的書籍或者大神寫的blog?
WPF如何判斷程序是不是第一次啟動?
微軟的.NET戰略是不是已經失敗了?

TAG:NET | C# | Net開發 |