13.3.1 호환성을 위한 고려 사항
호출 측에서 in 한정자를 사용하는 것이 선택적이다 보니 흥미로운 하위 호환성 문제를 야기하곤 한다. 메서드의 매개변수로 값 매개변수(한정자를 사용하지 않는 기본 방식) 대신 in 매개변수를 사용하는 경우에는 소스 수준에서는 호환이 되지만(호출 코드를 변경하지 않더라도 항상 재컴파일을 해야 함) 바이너리 수준에서는 호환되지 않는다(기존에 컴파일했던 어셈블리는 런타임 시에 메서드 호출이 실패하게 된다). 이것이 정확히 어떤 의미인지는 상황에 따라 조금 다를 수 있을 것 같다. 우선, 이미 배포된 어셈블리에 포함된 메서드를 호출할 때에 값 매개변수 대신 in 매개변수를 사용하는 경우를 생각해 보자.
• 해당 메서드에 접근할 수 있지만 이미 외부에서 널리 사용하고 있어 통제할 수 없다면(예를 들어 라이브러리를 NuGet에 배포했다든지) 브레이킹 체인지를 일으키며, 여타의 브레이킹 체인지와 동일하게 다루어져야 한다.
• 해당 메서드는 제한된 범위 내에서만 사용되고 새로운 어셈블리를 생성하기 위해서 호출 측 코드를 매번 재컴파일한다면(호출 측 코드를 변경할 수 없더라도), 아무런 문제도 발생하지 않는다.
• 해당 메서드가 개발 중인 어셈블리 내부에서만 사용된다면1 호출 측 코드를 매번 재컴파일 할 것이기 때문에 바이너리 호환성에 대해서 걱정할 필요가 없다.
드물게 발생하는 경우이긴 하지만 조금 다른 예도 살펴보자. 매개변수가 복사되는 것을 막기 위해서 참조 매개변수를 사용하는 메서드를 정의했고(메서드의 매개변수를 수정하지 않은 채), 이 메서드를 호출하기 위해서 in 매개변수를 사용하는 경우라면 바이너리 호환성은 유지되지만 소스 수준의 호환성은 유지되지 않는다. 이는 앞서 값 매개변수를 in 매개변수로 바꿨을 때와 완전히 반대다.
이러한 예는 in 매개변수를 사용하더라도 메서드가 수행하는 일 자체가 문제가 되지 않을 것이라고 가정하고 있다. 하지만 이런 가정이 늘 맞는 것은 아니다. 왜 그런지 살펴보자.
1 어셈블리에서 InternalsVisibleTo를 사용하는 경우에는 상황이 조금 복잡해진다. 이에 대한 세부적인 내용은 이 책의 범위를 벗어난다.