Подтвердить что ты не робот

Почему List.Sort() метод экземпляра, но 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

Почему они не реализованы одинаково - интуитивно для меня было бы более разумно, если бы они были как методами экземпляра?

4b9b3361

Ответ 1

Вопрос интересен тем, что он показывает детали системы типа .NET. Подобно типам значений, типам строк и делегатов, типы массивов получают специальное обращение в .NET. Самое примечательное странное поведение заключается в том, что вы никогда явно не объявляете тип массива. Компилятор позаботится об этом для вас с достаточной помощью дрожания. System.Array - абстрактный тип, вы будете получать выделенные типы массивов в процессе написания кода. Либо явно создавая тип [], либо используя общие классы, у которых есть массив в своей базовой реализации.

В довольно большой программе наличие сотен типов массивов не является чем-то необычным. Это нормально, но для каждого типа задействованы служебные данные. Это хранилище требуется только для типа, а не для его объектов. Самый большой кусок - это так называемая "таблица методов". В двух словах, это список указателей на каждый метод экземпляра типа. Как загрузчик классов, так и джиттер работают вместе, чтобы заполнить эту таблицу. Это обычно называют "v-table", но не совсем соответствует, таблица содержит указатели на методы, которые являются не виртуальными и виртуальными.

Вы можете видеть, где это возможно, дизайнеры были обеспокоены наличием большого количества типов с большими таблицами методов. Поэтому искали способы сократить накладные расходы.

Array.Sort() была очевидной целью.

Такая же проблема не относится к родовым типам. Большая разновидность дженериков, одна из многих, одна таблица методов может обрабатывать указатели метода для любого параметра типа ссылочного типа.

Ответ 2

Вы сравниваете два разных типа "контейнеров объектов":

MyList представляет собой общий набор типа List, класс оболочки типа int, где List<T> представляет строго типизированный список объектов. Сам класс List предоставляет методы для поиска, сортировки и управления содержащимися в нем объектами.

MyArray - это базовая структура данных типа Array. Массив не предоставляет такой же богатый набор методов, как List. Массивы могут одновременно быть одномерными, многомерными или зубчатыми, в то время как списки из коробки только одномерные.

Взгляните на этот вопрос, он дает более богатое обсуждение этих типов данных: Array versus List<T>: When to use which?

Ответ 3

Вероятно, это связано с наследованием. Класс Array не может быть получен вручную. Но как ни странно, вы можете объявить массив чего угодно и получить экземпляр System.Array, который строго типизирован, даже до того, как дженерики позволили вам иметь строго типизированные коллекции. Массив, по-видимому, является одной из тех магических частей рамки.

Также обратите внимание, что ни один из методов экземпляра, представленных в массиве, не массивно модифицирует массив. SetValue() кажется единственным, что меняет что-либо. Класс Array предоставляет множество статических методов, которые могут изменять содержимое массива, например, Reverse() и Sort(). Не уверен, что это значимо - может быть, кто-то здесь может дать некоторое представление о том, почему это дело.

Напротив, List<T> (который не был вокруг в течение 1 дня каркаса), а классы типа ArrayList (который был вокруг тогда) - это просто запущенные классы мельниц, не имеющие особого значения в рамках, Они предоставляют общий метод экземпляра .Sort(), так что, когда вы унаследовали от этих классов, вы получили бы эту функциональность или могли бы переопределить ее.

Однако эти методы сортировки все равно вышли из моды, так как методы расширения, такие как сортировка стиля Linq.OrderBy(), стали следующей эволюцией. Вы можете запросить и отсортировать массивы и списки и любой другой перечислимый объект с тем же механизмом, который действительно действительно приятный.

- EDIT -

Другим, более циничным ответом может быть только как это сделала Java, поэтому Microsoft сделала то же самое в версии 1.0 поскольку в то время они были заняты игрой в догонялки.

Ответ 4

Не спрашивая кого-то, кто был вовлечен в дизайн оригинальной платформы, это трудно понять. Но, вот моя догадка.

В более старых языках, таких как C, массивы - это немые структуры данных - у них нет собственного кода. Вместо этого им манипулируют внешние методы. Когда вы переходите в объектно-ориентированную структуру, ближайший эквивалент - это немой объект (с минимальными методами), управляемый статическими методами.

Итак, я предполагаю, что реализация .NET-массивов является скорее симптомом мышления стиля С в первые дни развития, чем что-либо еще.

Ответ 5

Одна из причин может заключаться в том, что Array.Sort был разработан в .NET 1.0, у которого не было никаких дженериков.

Ответ 6

Я не уверен, но я думаю, возможно, просто так, чтобы массивы были как можно ближе к Primitives.