더북(TheBook)

이 예제의 경우 int 자체가 그리 큰 타입은 아니기 때문에 효율성을 개선한다는 측면에서는 그다지 유용하지 않다. 하지만 크기가 큰 구조체를 사용하는 경우를 생각해 본다면 힙 할당과 가비지 수집에 상당한 도움이 될 것이다.

» 구현 세부 사항


IL 수준에서 보자면, ref readonly를 반환하는 메서드라 할지라도 일반적인 ref 반환 기능만을 이용하여 메서드를 정의한다(반환 타입이 by-ref 타입). 다만, System.Runtime.InteropServices 네임스페이스에서 정의하고 있는 [InAttribute] 특성을 메서드에 덧붙일 뿐이다. 이 특성은 이후 IL의 modreq 한정자로 치환된다. 만약 컴파일러가 InAttribute 특성을 이해하지 못하는 상황이라면, 메서드 호출 코드는 컴파일되지 않는다. 이는 메서드의 반환값이 잘못 사용되는 것을 미연에 방지하기 위한 메커니즘이다. C# 7.0 컴파일러(ref를 반환하는 것은 이해하지만, ref readonly를 반환하는 것은 이해하지 못하는)를 이용하여 개발된 어셈블리가 있고, 이 어셈블리 내에 ref readonly를 반환하는 외부 메서드를 호출하는 코드가 있다고 생각해 보자. 이것이 가능하다면 호출 측에서는 쓰기 가능한 참조 지역 변수에 메서드의 결괏값을 저장한 후, 그 값을 수정하려고 할 수도 있다. 이는 ref readonly를 반환하는 메서드의 의미를 퇴색시킨다.

컴파일러가 InAttribute 특성에 대해서 알지 못한다면 ref readonly를 반환하는 메서드를 컴파일할 수도 없다. 이 특성은 .NET 1.1 데스크톱 프레임워크와 .NET standard 1.1에도 정의되어 있는 특성이므로 이런 경우는 거의 발생하지 않지만, 만약 그런 경우라 해도 적절한 네임스페이스 내에 사용자가 해당 특성을 정의해 주기만 하면 컴파일러가 이 특성을 올바르게 사용할 것이다.

readonly 한정자는 앞서 살펴본 것처럼 지역 변수의 타입과 반환 타입 모두에 사용할 수 있었다. 그렇다면 매개변수에 대해서도 사용할 수 있을까? 읽기 전용 참조 지역 변수를 값을 복사하지 않고 다른 메서드에 전달하고 싶다면 어떻게 해야 할까? 매개변수에 대해서도 동일하게 readonly 한정자를 사용하면 될 것 같지만 실상은 조금 다르다. 다른 절에서 그 내용을 설명할 것이다.

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