정적 클래스 멤버를 올바르게 초기화하라
정적 멤버 변수를 포함하는 Class가 있다면 반드시 인스턴스 생성 전에 정적 멤버 변수를 먼저 초기화해야 한다.
하지만 정적 멤버 변수의 초기화 과정이 복잡하다면 C#에서 지원하는 정적 생성자를 사용하여 생성을 타이밍을 늦추는 방법도 있다.
정적 생성자는 해당 Class내의 멤버 변수를 최초로 접근하기 전에 자동으로 호출이 된다.
이 말인즉슨 정적 변수를 초기화하거나, 싱글톤 패턴을 적용하거나, 혹은 여타의 작업을 효율적으로 사용할 수 있다는 뜻인데 Lazy Initialization(늦은 초기화)를 진행하여 사용하기 전까지는 보류하고 있는 기능이다.
이전에 포스팅했던 생성자 관련해서도 일반적인 생성자처럼
1. 정적 멤버 초기화
2. BaseClass 정적 생성자 호출
3. 정적 생성자 호출
순서대로 실행이 된다.
2가지 예시로 설명을 하겠다.
1. 생성자가 단순하여 정적 생성자를 생략한 싱글톤 패턴
public class MySingleton
{
private static readonly MySingleton _mySingleton = new MySingleton();
public static MySingleton TheOnly
{
get
{
return _mySingleton;
}
}
private MySingleton(){ }
}
2. 생성자가 복잡하여(오버헤드가 큰 경우) 정적생성자를 사용한 싱글톤 패턴
public class MySingleton
{
private static readonly MySingleton _mySingleton;
static MySingleton()
{
_mySingleton = new MySingleton();
}
public MySingleton TheOnly
{
get
{
return _mySingleton;
}
}
private MySingleton(){}
}
정적 생성자에 대해서 정리하자면
1. AppDomain내에서 CLR이 특정 타입에 접근해야 할 경우 정적 생성자를 우선적으로 호출한다.
2. 정적 생성자는 모든 타입에 대해서 하나만 가질 수 있고 어떠한 매개변수도 허용하지 않는다.
3. CLR에서 정적 생성자를 호출할때 예외가 발생한 경우 프로그램을 언로드 하지 않는 한 정적생성자는 다시 호출되지 않는다. 따라서 개발자는 정적 생성자를 코딩한 경우 신중하게 다뤄야 한다.
4. 정적생성자를 사용해야 하는 경우에는 try/catch문으로 신중하게 다뤄야 한다.
예시 코드
static MySingleton()
{
try
{
_mySingleton = new MySingleton()
}
catch
{
//복구 시도
}
}
'Program > Effective C#' 카테고리의 다른 글
Effective C# ITEM15 (0) | 2020.11.03 |
---|---|
Effective C# ITEM14 (0) | 2020.10.28 |
Effective C# ITEM 12 (0) | 2020.10.26 |
Effective C# ITEM11 (0) | 2020.10.25 |
Effective C# ITEM10 (0) | 2020.10.21 |