방프리

20.05.12 Chapter2. .Net 리소스 관리 (Item 16) 본문

C#/Effective C#

20.05.12 Chapter2. .Net 리소스 관리 (Item 16)

방프리 2020. 5. 12. 22:36

Item 16: 생성자 내에서는 절대로 가상 함수를 호출하지 말라

 

C++과 C#에서 생성자가 동작하는 방식의 기준은 많이 다르다고 한다. 그로 인해 개발자들이 예상하는 값과는

전혀 다른 형태의 값을 출력할 때도 있다.

다음의 코드를 분석하면 C++ 개발자들은 보통 "VFunc in B" 이 출력될 것이라 생각하지만 C#은 생성자 구문에

인스턴스가 들어오면 초기화가 끝났다고 판명하기 때문에 선언과 동시에 초기화를 해준 "Set by initializer"가 

마지막으로 출력이 된다.

C++은 가상함수가 생성 중인 객체의 타입을 확인하도록 되어있으나, C#은 다르다. 또한 C#은 현재 타입이 추상 베이스 

클래스인 경우 가상 메서드가 null 메서드 포인터가 될 가능성을 배제하였다.

C#의 컴파일러는 런타입 때의 타입을 고려해 VFunc를 호출하지만 이는 굉장히 위험하다.

애초에 C++에서는 에러를 내지만 C#에서도 마찬가지로 어떠한 내용이 출력될 지는 예상하기 어렵다.

애초에 가상함수를 호출한다는 것은 그 베이스가 되는 클래스를 먼저 호출하는데 그에 대한 내용이 어떠한 것인지도

불분명할 뿐더러 어떠한 에러를 가져올 지 아무도 알 수 없다. 

차라리 이러한 위험부담을 안고 호출해야 한다면 처음부터 호출하지 않는 것이 좋다. 

Comments