Windows Runtime 구성 요소에 배열 전달
Windows 런타임에서 매개 변수는 입력을 위한 것이거나 출력을 위한 것이지 둘 다를 위한 것일 수는 없습니다. 즉 메서드에 전달되는 배열의 내용 및 배열 자체는 입력을 위한 것이거나 출력을 위한 것입니다. 배열의 내용이 입력용인 경우 메서드는 배열에서 읽지만 배열에 쓰지는 않습니다. 배열의 내용이 출력용인 경우 메서드는 배열에 쓰지만 배열에서 읽지는 않습니다. .NET Framework에서 배열은 참조 형식이고 배열 참조를 값으로 전달하는 경우에도(Visual Basic의 경우 ByVal) 배열의 내용은 변경할 수 있으므로 위와 같은 방식을 사용하면 배열 매개 변수에 문제가 발생할 수 있습니다. Windows Runtime Metadata Export Tool(Winmdexp.exe)에서는 컨텍스트로부터 배열의 용도를 분명히 알 수 없는 경우 매개 변수에 ReadOnlyArrayAttribute 특성 또는 WriteOnlyArrayAttribute 특성을 적용하여 해당 용도를 지정해야 합니다. 배열 용도는 다음과 같이 결정됩니다.
반환 값 또는 out 매개 변수(Visual Basic의 경우 OutAttribute 특성이 적용된 ByRef 매개 변수)의 경우 배열은 언제나 출력 전용입니다. ReadOnlyArrayAttribute 특성을 적용하지 마십시오. 출력 매개 변수에 WriteOnlyArrayAttribute 특성을 사용할 수는 있지만 이는 중복된 동작입니다.
경고
Visual Basic 컴파일러는 출력 전용 규칙을 적용하지 않습니다.출력 매개 변수에서는 절대로 읽지 말아야 합니다. 출력 매개 변수에는 Nothing이 포함되어 있을 수 있습니다.항상 새 배열을 할당하세요.
ref 한정자(Visual Basic의 ByRef)가 있는 매개 변수는 허용되지 않습니다. Winmdexp.exe(Windows Runtime 메타데이터 내보내기 도구)에서 오류가 생성됩니다.
값으로 전달되는 매개 변수의 경우 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 런타임 구성 요소에 대해 작성된 단위 테스트에 영향을 미치므로 반드시 기억해 두어야 합니다. 테스트가 관리 코드로 작성된 경우에는 테스트하는 동안 배열 내용이 변경 가능한 것으로 나타날 것입니다.