И почему они (команда c #) сделали
этот дизайн (я имею в виду, почему это не
что-то вроде массива ...
Обобщения идеально подходят для определения контейнера, поскольку они ограничивают тип элемента, поэтому вы не можете вставить тип A и попытаться получить тип B.
Но генерики не были добавлены до CLR2 / C # 2. Таким образом, массивы должны были обеспечивать безопасность типов по-своему.
Несмотря на это, это не так уж отличается от дженериков. Вы заметите, что нет специального класса для int[]
. Но и не будет для Array<int>
. В дженериках будет только дженерик-класс Array<T>
, и CLR «волшебным образом» создает специализированные версии для аргументов различных типов, которые вы используете. Так что было бы не менее "волшебно", если бы использовались дженерики.
Несмотря на это, в CLR тип любого объекта определяется (он существует как значение, которым вы можете манипулировать), типа Type
и может быть получен с помощью typeof
. Таким образом, хотя нет никакого объявления кода какого-либо типа массива (и зачем вам его нужно видеть?), Существует объект Type
, к которому можно обратиться.
Кстати, в том, как массивы ограничивают типы элементов, был недостаток конструкции. Вы можете объявить массив:
int[] ints = ...
Затем вы можете сохранить его в более свободной переменной:
object[] objs = ints;
Но это означает, что вы можете вставить строку (по крайней мере, так будет во время компиляции):
objs[3] = "Oh dear";
Во время выполнения выдает исключение. Идея статической проверки типов заключается в том, чтобы отлавливать подобные вещи во время компиляции, а не во время выполнения. Обобщения не имели бы этой проблемы, потому что они не обеспечивают совместимость присваивания экземплярам обобщенного класса на основе совместимости их параметров типа. (Начиная с C # 4 / CLR4 они получили возможность делать это там, где это имеет смысл, но это не имеет смысла для изменяемого массива.)