더북(TheBook)

예제 13-12 in 매개변수에 대해 인수를 전달할 때 유효한 경우와 유효하지 않은 경우 ▶ InParameterOptions.cs

static void PrintDateTime(in DateTime value)  ----- in 매개변수를 취하는 메서드 정의
{
    string text = value.ToString(
        "yyyy-MM-dd'T'HH:mm:ss",
        CultureInfo.InvariantCulture);
    Console.WriteLine(text);
}

static void Main()
{
    DateTime start = DateTime.UtcNow;
    PrintDateTime(start);  ----- 암시적으로 변수의 참조를 전달
    PrintDateTime(in start);  ----- 명시적으로 변수의 참조를 전달(in 한정자가 사용되었으므로)
    PrintDateTime(start.AddMinutes(1)); ----- 보이지 않는 지역 변수 복사본을 생성한 후 이에 대한 참조를 전달
    PrintDateTime(in start.AddMinutes(1)); ----- 컴파일 시 오류: 인수를 참조로 전달할 수 없음
}

생성된 IL을 살펴보면, 이러한 매개변수는 System.Runtime.CompilerServices 네임스페이스에서 정의하고 있는 [IsReadOnlyAttribute]가 덧붙여진 참조 타입으로 컴파일된다. 이 특성은 InAttribute보다는 최근에 추가되었는데, .NET 4.7.1부터 포함되기 시작했고 .NET Standard 2.0에는 아예 포함되지도 않았다. IsReadOnlyAttribute를 사용하기 위해서 다른 라이브러리를 추가하거나 해당 특성을 직접 정의하는 것은 꽤나 번거로운 일이기 때문에, 컴파일러는 IsReadOnlyAttribute 특성을 찾지 못하면 이 특성을 자체적으로 생성해 버린다.

이 특성은 IL 수준에서 modreq 한정자로 치환되지 않으며, IsReadOnlyAttribute를 이해하지 못하는 컴파일러를 사용하는 경우, 이를 일반적인 참조 매개변수로 처리해 버린다(CLR도 이 속성에 대해서는 알 필요가 없다). 이런 이유로 ref를 사용하지 않고 in을 사용하는 코드의 경우, 최신 컴파일러로 재컴파일했을 때 갑자기 컴파일 오류가 발생하는 경우가 발생할 수 있다. 이는 하위 호환성이라는 큰 문제를 야기하게 된다.

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.