-객체를 완전히 생성하기전에 가상함수(virtual)를 호출하면 이상동작을 일으킨다.
-어떤 타입이든 생성자가 작업을 완료할떄까지 객체가 완전히 생성되었다고 볼 수 없다.

-class B는 생성자를 호출 할때 가상함수 VFunc를 호출한다.
-class B를 상속 받는 Derived 클래스는 생성자가 호출될 때 msg를 쓰는 메서드를 호출한다.
-Vfunc는 오버라이드 되어 런타임에 재정의한 함수가 발동한다.
-msg 변수는 'Set by intializer'를 기본이고 main 객체가 만들어질 때는 'Constructed in main'를
쓰도록 작성되있다.
-그렇지만 쓰여지는 것은 'Set by intializer'이다.
-C#에서 생성자의 본문으로 진입하는 순간 해당 객체는 이미 초기화가 완료되었다고 간주하기에
Derived의 생성자에서 msg가 this.msg = msg로 초기화되지 않은 상태에서 Derived.VFunc()가 수행된다.

-위 코드는 class B를 추상클래스 만들었다. 추상클래스는 객체를 만들 수 없고
파생클래스인 Derived는 VFunc() 구현해야한다.
-그래서 C#은 런타임에 타입 고려하여 VFunc()를 호출하여 런타임 예외가 발생하지 않는다.
-하지만 가상함수처럼 의도치않은 오류가 날 수 있다.
-readonly 로 선언된 msg의 값은 생성자가 완료될 떄까지 변경이 생길 수 있다.
-생성자가 수행중 일떈 멤버변수는 어떠한 값도 갖고 있지 않는 상태로 간주해야하는 것이 옳다.
결론:생성자 내에서는 절대로 가상함수를 호출하지 말자.
'C# > 이펙티브 C#' 카테고리의 다른 글
| 아이템15.불필요한 객체를 만들지 마라 (0) | 2023.07.19 |
|---|---|
| 아이템 13. 정적 클래스 멤버를 올바르게 초기화하라. (0) | 2023.07.05 |
| 아이템12. 할당 구문보다 멤버 초기화 구문이 좋다. (0) | 2023.07.03 |
| 아이템11. NET 리소스 관리에 대한 이해 (0) | 2023.07.02 |
| 아이템9.박싱과 언박싱을 최소화하라. (0) | 2023.06.30 |