더북(TheBook)

이 코드를 해석해 보면 우선 필드의 값을 읽어서 스택에 그 값을 복사한다. 다음으로 Year 속성을 얻기 위해 게터 역할을 하는 get_Year() 멤버를 호출한다. 이 코드를 읽고 쓸 수 있는 필드에 접근하는 IL 코드와 비교해 보자.

ldflda valuetype YearMonthDay ImplicitFieldCopy::readWriteField
call instance int32 YearMonthDay::get_Year()

이 코드를 보면 ldfld 명령어를 사용해서 필드의 값을 로드했던 이전 코드와는 달리, ldflda 명령어를 사용해서 필드의 주소를 로드한다는 것을 알 수 있다. IL로 작성된 코드는 컴퓨터가 직접 수행하지는 않는다. 가끔은 JIT 컴파일러가 이러한 내용들을 모두 최적화해 버릴 수도 있다. 하지만 Noda Time을 개발하면서 경험한 바에 따르면, 읽고 쓸 수 있는 필드를 사용하는 편이 성능적으로 훨씬 큰 이득이 있었다.

이처럼 컴파일러가 복사본을 구성하는 이유는 읽기 전용 필드가 속성 내부의 코드(혹은 메서드나 사용자가 호출할 수 있는 그 무엇)에 의해서 변경되는 것을 방지하기 위함이다. 읽기 전용 필드를 작성하는 의도가 결국 값을 변경하지 못하도록 하기 위한 것이기 때문이다. readOnlyField.SomeMethod()가 필드의 값을 수정할 수 있다면 그게 더 이상한 것이다. C#에서 속성 세터 내에서는 데이터를 변경할 수 있도록 설계되었지만 읽기 전용 필드의 값은 변경할 수 없다. 하지만 세터가 아닌 속성 게터 내에서 값을 변경하려고 할 수 있을 텐데, 설사 이것이 허용된다 하더라도 복사본에 대해서 변경이 수행될 것이므로 읽기 전용 필드는 변경되지 않는다. 이처럼 내용을 복사하는 것은 효과적인 안전 조치임이 분명하다.

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