# 멤버 초기화 구문이 좋은 이유
. 생성자가 여러 개일 때도 멤버 변수 초기화를 누락하지 않도록 미연에 방지할 수 있다.
(다만, 모든 생성자가 동일한 방법으로 멤버 변수를 초기화하는 경우에 한해서 사용해야 한다. )
. 가독성이 좋고, 유지보수도 용이하다.
# 초기화 구문의 특성
. 컴파일러는 모든 생성자(생성자가 없는 경우에 생성하는 기본생성자 포함)의 시작 부분에 멤버 초기화 구문을 포함시키기 때문에 새로운 생성자를 추가하더라도 항상 멤버 초기화 구문이 포함된다.
. 또한, 생성하려는 타입이 클래스를 상속하고 있는 경우 베이스 클래스의 생성자가 호출되기 전에 멤버에 대한 초기화가 이루어진다.
. 멤버 변수의 초기화 순서는 변수의 선언 순서이다.
# 사용 방법
변수를 선언하는 곳에 변수를 초기화 하도록 작성하기만하면 된다.
public class MyClass { //컬렉션 선언과 동시에 초기화 private List<string> labels = new List<string>(); }
# 주의해야할 경우
1. 객체를 0이나 null로 초기화하는 경우.
기본 시스템 초기화 루틴은 코드를 실행하기 전에 모든 값을 0으로 설정한다.
그런데 객체를 0이나 null로 초기화 하게되면, C#컴파일러는 개의치 않고 코드를 생성하기 때문에 괜한 일을 추가적으로 하는 꼴이 된다.
public struct MyValType { // 생략 } MyValType myVal1; // 0으로 초기화 MyValtype myVal2 = new MyValType(); // 반복해서 0으로 초기화
myVal2같은 경우 initobj라는 IL 명령을 사용하는데 박싱/언박싱 된 myVal2 변수 모두에 대해서 0으로 초기화 하는 과정이 수행된다.
이 과정으로 인해 약간의 추가 시간이 소요된다.
2. 동일한 객체를 반복해서 초기화하는 경우.
public class MyClass2 { private List<string> labels = new List<string>(); MyClass2() { } MyClass2(int size) { labels = new List<string>(size); } }
위와 같이 List 객체를 생성하는 방식이 다양하게 혼재하는 경우 멤버 초기화 구문을 사용하지 않는 것이 좋다.
MyClass2를 생성할 때 컬렉션의 크기를 지정하게 되면 실제로 2개의 List<> 객체가 생성되며 그 중 하나는 즉각 가비지가 된다.
멤버 초기화 구문은 생성자의 본문보다 앞서 수행되므로 생성자 본문에서 생성한 객체만 살아남는다.
3. 예외처리가 반드시 필요한 경우.
멤버 초기화 구문은 try로 감쌀 수 없기 때문에 초기화 과정에서 예외가 발생하면 예외가 외부로 전파된다. 따라서 클래스 내부에서 복구를 시도할 수가 없다.
예외처리가 필요하다면 반드시 생성자 내부에서 처리해야만 한다.
'책 > Effective C#' 카테고리의 다른 글
Item 11. .NET 리소스 관리에 대한 이해 (0) | 2019.04.17 |
---|---|
Item 10. 베이스 클래스가 업그레이드된 경우에만 new 한정자를 사용하라. (0) | 2019.04.08 |
Item 9. 박싱과 언박싱을 최소화하라. (0) | 2019.04.05 |
Item 8. 이벤트 호출 시에는 null 조건 연산자를 사용하라. (0) | 2019.04.04 |
Item 7. 델리게이트를 이용하여 콜백을 표현하라. (0) | 2019.03.27 |