Передача массивов в компонент среды выполнения Windows
Параметры Среда выполнения Windows могут быть либо входными, либо выходными, но никогда входными и выходными одновременно. Это означает, что содержимое массива, передаваемого методу, а также сам массив должны быть предназначены для ввода или для вывода. Если содержимое массива предназначено для ввода, метод считывает массив, но не записывает в него. Если содержимое массива предназначено для вывода, метод записывает массив, но не считывает его. В результате возникает проблема с параметрами массива, поскольку массивы в .NET Framework представляют собой ссылочные типы и содержимое массива является изменяемым, даже если ссылка на массив передается по значению (ByVal в Visual Basic). Средство экспорта метаданных среды выполнения Windows (Winmdexp.exe) обязывает указывать назначение массива, если это не очевидно из контекста, путем применения к параметру атрибута ReadOnlyArrayAttribute или WriteOnlyArrayAttribute. Назначение массива определяется следующим образом.
Для возвращаемого значения или для параметра out (параметра ByRef с атрибутом OutAttribute в Visual Basic), массив всегда предназначен только для вывода. Не применяйте атрибут ReadOnlyArrayAttribute. Атрибут WriteOnlyArrayAttribute допускается в выходных параметрах, но является избыточным.
Предупреждение
Компилятор Visual Basic не применяет принудительно правила только для вывода.Никогда не следует выполнять чтение выходного параметра; он может содержать значение Nothing.Всегда присваивайте новый массив.
Параметры с модификатором ref (ByRef в Visual Basic) не допускаются. Winmdexp.exe (средство экспорта метаданных среды выполнения Windows) создает ошибку.
Для параметра, который передается по значению, необходимо определить, предназначено ли содержимое массива для ввода или вывода, путем применения атрибута ReadOnlyArrayAttribute или WriteOnlyArrayAttribute. Указание обоих атрибутов приведет к ошибке.
Если метод должен принять входной массив, изменить содержимое массива и возвратить массив вызывающему объекту, используйте доступный только для чтения параметр для ввода и доступный только для записи параметр (или возвращаемое значение) для вывода. В следующем коде демонстрируется один из способов реализации этой модели.
public int[] ChangeArray([ReadOnlyArray()] int[] input)
{
int[] output = input.Clone();
// Manipulate the copy.
// ...
return output;
}
Public Function ChangeArray(<ReadOnlyArray> input() As Integer) As Integer()
Dim output() As Integer = input.Clone()
' Manipulate the copy.
' ...
Return output
End Function
Рекомендуется создать копию входного массива и работать с этой копией. Это гарантирует одинаковое поведение метода независимо от того, вызывается ли компонент кодом .NET Framework или нет.
Использование компонентов из управляемого и машинного кода
Параметры с атрибутом ReadOnlyArrayAttribute или WriteOnlyArrayAttribute могут вести себя по-разному в зависимости кода, с помощью которого написан вызывающий объект, — машинного или управляемого. Если вызывающий объект является машинным кодом (JavaScript или Расширения компонентов Visual C++), содержимое массива обрабатываются следующим образом.
Атрибут ReadOnlyArrayAttribute: если вызов пересекает границу интерфейса ABI, массив копируется. При необходимости элементы преобразуются. Поэтому все случайные изменения, которые метод применяет к массиву, предназначенному только для ввода, не видны вызывающему объекту.
Атрибут WriteOnlyArrayAttribute: вызываемый метод не может делать предположения о содержимом исходного массива. Например, получаемый методом массив мог быть не инициализирован или содержать значения по умолчанию. Предполагается, что метод устанавливает значения всех элементов массива.
Если вызывающий объект является управляемым кодом, исходный массив доступен вызываемому методу, как в случае любого вызова массива в .NET Framework. Содержимое массива доступно для изменения в коде .NET Framework, поэтому все изменения, которые метод вносит в массив, видны вызывающему объекту. Это важно помнить, поскольку подобное поведение влияет на модульные тесты, написанные для компонента Среда выполнения Windows. Если тесты пишутся с помощью управляемого кода, содержимое массива будет отображаться как изменяемое во время тестирования.
См. также
Ссылки
Основные понятия
Создание компонентов среды выполнения Windows в C# и Visual Basic