簡體   English   中英

為什么 List.Sort() 是實例方法,而 Array.Sort() static?

[英]Why is List.Sort() an instance method but Array.Sort() static?

我試圖理解這部分語言背后的設計決策。 我承認我對這一切都很陌生,但這是最初讓我感到困惑的事情,我想知道我是否錯過了一個明顯的原因。 考慮以下代碼:

List<int> MyList = new List<int>() { 5, 4, 3, 2, 1 };
int[] MyArray = {5,4,3,2,1};


//Sort the list
MyList.Sort();
//This was an instance method


//Sort the Array
Array.Sort(MyArray);
//This was a static method

為什么它們不是以相同的方式實現 - 直觀地對我來說,如果它們都是實例方法會更有意義?

這個問題很有趣,因為它揭示了 .NET 類型系統的細節。 與值類型、字符串和委托類型一樣,數組類型在 .NET 中得到特殊處理。 最值得注意的奇怪行為是您從不顯式聲明數組類型。 編譯器會為您提供充足的抖動幫助。 System.Array 是一種抽象類型,您在編寫代碼的過程中會得到專用的數組類型。 通過顯式創建 type[] 或使用在其基本實現中具有數組的泛型類。

在大型程序中,擁有數百種數組類型並不罕見。 沒關系,但是每種類型都涉及開銷。 它只是類型所需的存儲,而不是它的對象。 其中最大的一塊是所謂的“方法表”。 簡而言之,它是指向該類型的每個實例方法的指針列表。 class 加載器和抖動一起工作以填充此表。 這通常稱為“v-table”,但並不完全匹配,該表包含指向非虛擬和虛擬方法的指針。

你可以看到這可能會導致什么,設計者擔心有很多類型帶有大的方法表。 因此,尋找減少開銷的方法。

Array.Sort() 是一個明顯的目標。

同樣的問題與泛型類型無關。 generics 的一大優點,一個方法表可以處理引用類型的任何類型參數的方法指針。

您正在比較兩種不同類型的“對象容器”:

MyListList類型的通用集合,它是一個包裝器 class,類型為int ,其中List<T>表示對象的強類型列表。 列表 class 本身提供了搜索、排序和操作其包含的對象的方法。

MyArrayArray類型的基本數據結構。 Array 沒有提供與 List 相同的豐富方法集。 Arrays 可以同時是一維、多維或鋸齒狀,而開箱即用的列表僅是一維的。

看看這個問題,它提供了關於這些數據類型的更豐富的討論: Array versus List<T>: When to use which?

這可能與 inheritance 有關。 陣列 class 無法手動派生。 但奇怪的是,即使在 generics 允許您擁有強類型 collections 之前,您也可以聲明任何東西的數組並獲得一個強類型的 System.Array 實例。 數組似乎是框架中那些神奇的部分之一。

另請注意,數組上提供的實例方法都不會大量修改數組。 SetValue()似乎是唯一改變任何東西的方法。 Array class 本身提供了許多可以改變數組內容的 static 方法,例如 Reverse() 和 Sort()。 不確定這是否重要 - 也許這里有人可以提供一些背景來說明為什么會這樣。

相比之下, List<T> (在 1.0 框架時代不存在)和像ArrayList類的類(當時存在)只是普通類,在框架內沒有特殊含義。 它們提供了一個 common.Sort() 實例方法,因此當您從這些類繼承時,您將獲得該功能或可以覆蓋它。

然而,這些排序方法已經過時了,因為像 Linq's.OrderBy() 樣式排序這樣的擴展方法已經成為下一個演變。 您現在可以使用相同的機制查詢和排序 arrays 和列表以及任何其他可枚舉的 object,這非常非常好。

- 編輯 -

另一個更憤世嫉俗的答案可能是——這就是 Java 的做法,所以微軟在 1.0 版本的框架中也是這樣做的,因為當時他們正忙着追趕。

如果不問參與原始平台設計的人,很難知道。 但是,這是我的猜測。

在較舊的語言中,例如 C、arrays 是愚蠢的數據結構——它們沒有自己的代碼。 相反,它們被外部方法操縱。 當您進入面向 Object 的框架時,最接近的等價物是由 static 方法操作的啞 object(使用最少的方法)。

所以,我的猜測是,.NET Arrays 的實現更像是 C 風格思維在開發初期的症狀。

一個原因可能是因為Array.Sort是在 .NET 1.0 中設計的,它沒有 generics。

我不確定,但我在想也許只是為了讓 arrays 盡可能接近 Primitives。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM