Почему List.Sort () метод экземпляра, но Array.Sort () static?
Я пытаюсь понять конструктивное решение этой части языка. Я признаю, что я очень новичок в этом, но это то, что меня поймало изначально, и мне было интересно, не хватает ли я очевидной причины. Рассмотрим следующий код:
List MyList = new List() { 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
Почему они не оба реализованы одинаково – интуитивно для меня было бы более разумно, если бы они были как методами экземпляра?
- EF, включая другие объекты (шаблон общего репозитория)
- Сортировка std :: map с использованием значения
- C ": функция возвращает адрес локальной переменной"
- Отражение. Получение общих параметров из экземпляра System.Type.
- В C ++ существует ли еще плохая практика вернуть вектор из функции?
- В чем разница между static_cast и стилем стиля C?
- Как strtok () разбивает строку на токены в C?
- Почему bit endianness является проблемой в битполях?
- Получение размеров изображения без чтения всего файла
- Размер объекта C ++ с виртуальными методами
- Где хороший адресный парсер
- A .net дизассемблер / декомпилятор
- Самый быстрый способ определить, существует ли целое число между двумя целыми числами (включительно) с известными наборами значений
Вопрос интересен тем, что он показывает детали системы типа .NET. Подобно типам значений, типам строк и делегатов, типы массивов получают специальное обращение в .NET. Самое примечательное странное поведение заключается в том, что вы никогда явно не объявляете тип массива. Компилятор позаботится об этом для вас с достаточной помощью дрожания. System.Array – абстрактный тип, вы будете получать выделенные типы массивов в процессе написания кода. Либо явно создавая тип [], либо используя общие classы, которые имеют массив в своей базовой реализации.
В довольно большой программе наличие сотен типов массивов не является чем-то необычным. Это нормально, но для каждого типа есть накладные расходы. Это хранилище требуется только для типа, а не для его объектов. Самый большой кусок – это так называемая «таблица методов». В двух словах, это список указателей на каждый метод экземпляра типа. Как загрузчик classов, так и джиттер работают вместе, чтобы заполнить эту таблицу. Это обычно называется «v-table», но не совсем соответствует, в таблице содержатся указатели на не виртуальные и виртуальные методы.
Вы можете видеть, где это возможно, дизайнеры были обеспокоены наличием большого количества типов с большими таблицами методов. Поэтому искали способы сократить накладные расходы.
Array.Sort () была очевидной целью.
Эта же проблема не относится к общим типам. Большая разновидность дженериков, одна из многих, одна таблица методов может обрабатывать указатели метода для любого параметра типа ссылочного типа.
Вы сравниваете два разных типа «контейнеров объектов»:
MyList
– это общая коллекция типа List , class оболочки, типа int
, где List
представляет строго типизированный список объектов. Сам class List предоставляет методы поиска, сортировки и управления содержащимися в нем объектами.
MyArray
– это базовая структура данных типа Array . Массив не предоставляет такой же богатый набор методов, как List. Массивы могут одновременно быть одномерными, многомерными или зубчатыми, в то время как списки из коробки только одномерные.
Взгляните на этот вопрос, он дает более богатое обсуждение этих типов данных: Array versus List
Не спрашивая кого-то, кто был вовлечен в дизайн оригинальной платформы, это трудно понять. Но, вот моя догадка.
В более старых языках, таких как C, массивы – это немые структуры данных – у них нет собственного кода. Вместо этого им манипулируют внешние методы. Когда вы переходите в объектно-ориентированную структуру, ближайший эквивалент – это немой объект (с минимальными методами), управляемый статическими методами.
Итак, я предполагаю, что реализация .NET-массивов является скорее симптомом мышления стиля С в первые дни развития, чем что-либо еще.
Скорее всего, это связано с наследованием. Класс Array не может быть получен вручную. Но как ни странно, вы можете объявить массив чего угодно и получить экземпляр System.Array, который строго типизирован, даже до того, как дженерики позволили вам иметь строго типизированные коллекции. Кажется, что массив является одной из тех магических частей frameworks.
Также обратите внимание, что ни один из методов экземпляра, предоставляемых в массиве, не массивно модифицирует массив. SetValue()
кажется единственным, что меняет что-либо. Класс Array предоставляет множество статических методов, которые могут изменять содержимое массива, например, Reverse () и Sort (). Не уверен, что это важно – может быть, кто-то здесь может дать некоторое представление о том, почему это так.
Напротив, List
(который не был в течение 1 дней каркаса), а classы, такие как ArrayList
(который был вокруг тогда), являются просто запущенными classами, не имеющими особого значения в рамках. Они предоставляют общий метод экземпляра .Sort (), так что, когда вы унаследовали от этих classов, вы получили бы эту функциональность или могли бы переопределить ее.
Тем не менее, эти методы сортировки вышли из моды в любом случае, поскольку методы расширения, такие как сортировка стиля Linq .OrderBy (), стали следующей эволюцией. Теперь вы можете запросить и отсортировать массивы и списки и любой другой перечислимый объект с тем же механизмом, который действительно действительно хорош.
— РЕДАКТИРОВАТЬ —
Другим, более циничным ответом может быть только то, как это сделала Java, поэтому Microsoft сделала то же самое в версии 1.0, поскольку в то время они были заняты игрой в догонялки.
Одна из причин может заключаться в том, что Array.Sort
был разработан в .NET 1.0, у которого не было никаких дженериков.
Я не уверен, но я думаю, может быть, просто так, чтобы массивы были как можно ближе к Primitives.