참치김밥은 최고의 한식이다

[Effective C# 2판] Item 5 : 값 타입에서는 0이 유효한 상태가 되도록 설계하라 본문

책/C#

[Effective C# 2판] Item 5 : 값 타입에서는 0이 유효한 상태가 되도록 설계하라

l__j__h 2024. 2. 21. 13:12

.NET은 기본적으로 모든 객체를 0으로 초기화한다. 따라서 0이 타입의 기본값이 되도록 설정하는 것이 좋다.

열거형(enum)은 좀 특별한 사례다. 열거형은 반드시 0을 유효한 값으로 선언해야 한다. 열거형 멤버를 선언하면, 그 값이 0으로 초기화되기 때문이다.

public enum Planet{
	Mercury = 1,
	Venus = 2,
	Earth = 3,
	Mars = 4,
	...
	Neptune = 8
}

Planet sphere = new Planet();

위 코드는 0일 때를 구현해놓지 않았다. 즉, sphere의 값은 0으로 초기화되어 유효하지 않은 값을 지니게 된다. 따라서 열거형을 아래처럼 변경하는 것이 좋다.

public enum Planet{
	None = 0,
	Mercury = 1,
	Venus = 2,
	Earth = 3,
	Mars = 4,
	...
	Neptune = 8
}

 

 


 

많은 개발자가 플래그로 사용하는 열거형에 대해서 비트 AND 연산자를 사용하곤 한다. 불행히도, 비트 연산시에 0이라는 값은 큰 문제를 일으킨다. 예를 들어, 다음 코드에서는 you값(None이 아닌, 무언가 유효한 값)을 0으로 정의하였다면 제대로 실행되지 않는다.

Styles flag = Styles.me;
if((flag & Styles.you) != 0) // Flat == 0 이면 항상 false가 된다.
	DoSomething();

 


 

아래는 구조체(값타입)를 정의할 때, 참조를 필드로 포함하는 경우 발생하는 초기화 문제이다. 참조타입은 null로 초기화되곤 한다. 이 문제의 대표적인 예로, 문자열(string)이 있다.

public struct LogMessage{
	private int ErrLevel;
	private string msg;
}

LogMessage myMessage = new LogMessage();

 

myMessage의 msg 필드는 null이다. 시스템상, 다른 값으로 초기화되게 할 수는 없다. 하지만, 프로퍼티를 사용하면 문제를 최소화할 수 있다. msg값을 노출하는 프로퍼티를 만들고, null 대신 빈 문자열을 반환하도록 코드를 추가하는 것이다.

 

public struct LogMessage{
	private int ErrLevel;
	private string msg;

	public string Message{
		get => msg ?? string.Empty; //??은 만일 좌측의 변수가 null이라면? 을 뜻한다.
		set => msg = value;
}
}

 

LogMessage 안에서도 msg 대신 MEssage 프로퍼티를 사용하는 것이 좋다. 위와 같이 정의된 프로퍼티를 사용하면, null검사를 따로 할 필요가 없기 때문이다.

728x90