정적 멤버 변수를 포함하는 타입이 있다면 인스턴스를 생성하기 전에 반드시 정적 멤버 변수를 초기화 해야한다.
C#에서는 정적 멤버 초기화 구문과 정적 생성자라는 두 가지 기능을 제공한다.
예시
static MyClass()는 정적 생성자이며 클래스가 처음으로 사용될 때 한 번만 호출된다. 이를 통해 정적 멤버 변수 myPiggy를 초기화 할 수 있다.
public class MyClass
{
// 정적 멤버 변수
public static int myPiggy;
// 정적 멤버 초기화 구문
static MyClass()
{
myPiggy = 42;
}
}
정적 생성자를 사용하는 대표적 사례 : 싱글톤 패턴
인스턴스가 하나만 생성되도록 보장하는 디자인 패턴 중 하나이다. 정적 생성자를 사용하여 구현할 때 정적 멤버 변수를 초기화하고 유일한 인스턴스를 생성한다.
01 정적 멤버를 간단히 초기화 하는 경우
theOneAndOnly 정적 멤버 변수는 클래스가 처음으로 사용될 때 한 번만 초기화되고 유지된다.
public class MySingleton
{
// 1. 정적 멤버 변수 선언 및 초기화
private static readonly MySingleton theOneAndOnly = new Singleton();
// 2. 정적 프로퍼티
public static MySingleton TheOnly{get{ return theOneAndOnly; }}
// Private 생성자
private MySingleton()
{
// 외부에서 직접 인스턴스 생성 방지
}
}
02 정적 생성자 버전
정적 생성자를 활용하여 초기화 과정을 더 복잡하게 처리할 수 있다. 정적 생성자는 클래스가 처음으로 사용될 때 호출되며 해당 호출 이전에 정적 멤버 변수인 theOneAndOnly를 초기화 시킨다. 이러한 방식으로 복잡한 초기화 로직이나 여러 단계를 거치는 작업을 수행할 수 있다.
public class MySingleton2
{
// 1. 정적 멤버 변수 선언
private static readonly MySingleton2 theOneAndOnly;
// 2. 정적 생성자
static MySingleton2()
{
// 정적 멤버 변수 초기화
theOneAndOnly = new MySingleton2();
}
// 정적 프로퍼티
// TheOnly가 호출될때 theOneAndOnly가 반환된다.
public static MySingleton2 TheOnly{ get{return theOneAndOnly;}}
// Private 생성자
private MySingleton2()
{
// 외부에서 직접 인스턴스 생성 방지
}
}
인스턴스 멤버 초기화 구문과 마찬가지로 정적 멤버 초기화 구문 또한 정적 생성자가 호출되기 이전에 실행되며 베이스 클래스의 정적 생성자보다 먼저 호출된다.
03 반드시 정적 생성자를 사용해야 하는 경우 : 예외가 발생할 가능성이 있는 경우
멤버 초기화 구문 대신 반드시 정적 생성자를 사용해야 할 때도 있다. 바로 예외가 발생할 가능성이 있는 경우인데, 멤버 초기화 구문의 경우 예외를 잡아낼 방법이 없기 떄문이다. 정적 생성자를 이용하면 다음과 같이 코드를 작성할 수 있다.
static MySingleton2()
{
try
{
theOneAndOnly = new MySingleton2();
}
catach
{
// 복구를 시도한다.
}
}
결론
정적 멤버 변수를 포함하는 타입이 있다면 인스턴스를 생성하기 전에 반드시 정적 멤버 변수를 초기화 해야한다.
본 게시글은 Effective C#을 읽고 정리하였습니다.
'책 > Effective C#' 카테고리의 다른 글
Effective C# - Item 15 불필요한 객체를 만들지 말라 (0) | 2023.12.03 |
---|---|
Effective C# - Item14 초기화 코드가 중복되는 것을 최소화하라 (0) | 2023.12.03 |
Effective C# - Item12 할당 구문보다 멤버 초기화 구문이 좋다 (0) | 2023.11.30 |
Effective C# - Item11 .NET 리소스 관리에 대한 이해 (0) | 2023.11.29 |
Effective C# - Item10 베이스 클래스가 업그레이드된 경우에만 new 한정자를 사용하라 (0) | 2023.11.22 |
댓글