- foo не может использовать ref/out/% или какие-либо дополнительные параметры.
- фактический параметр foo должен быть Object^.
Вызывающий может выделить массив и передать его, и вы можете изменить элементы внутри массива, но это просто приведение массива к Object и обратно.
Если вы хотите изменить фактический массив — например, присвоить его новому массиву другой длины, не используя ref
(%
в C++/CLI) или out
([Out]
в C++/CLI), вы не можете этого сделать.
Вот почему:
Виртуальная машина .NET работает, помещая объекты в стек и извлекая их из него. То, как вы передаете параметры функциям, за кулисами работает следующим образом:
- Вы помещаете параметры (в данном случае ссылку на массив) в стек.
- Вы вызываете функцию
- Виртуальная машина настраивается на вызов метода, считывая эти значения из стека в указанном порядке и присваивая их локальным переменным в вашей функции.
- Код внутри функции запускается.
Если вызывающая сторона не помещает действительные данные в стек перед вызовом функции, происходит сбой. Если вызывающий помещает данные в неправильном порядке - происходит сбой. Если со стеком вообще что-то смешное - он вылетает.
Кроме того, методы не могут изменять объекты, которые уже находятся в стеке. (Если бы они это сделали, они бы испортили стек — он зависает), они могут только вставлять и извлекать новые вещи из стека.
Это означает две вещи:
Чтобы вызвать функцию, вы должны поместить ссылку на массив в стек. Поэтому вызывающая сторона должна выделить сам массив или передать нулевую ссылку.
Вы не можете изменить ссылку на массив, поэтому функция не может предоставить новый массив. Поскольку массивы по своей природе неизменяемы, это означает, что вы не можете добавлять новые элементы (однако вы можете изменять существующие элементы).
Отказ от ответственности: Эрик Липперт, вероятно, придет и объяснит, почему все, что я только что написал, неверно, но, насколько мне известно и проведено исследование, именно так это и работает
person
Orion Edwards
schedule
08.01.2010