[Effective C# item 13] 정적 클래스 멤버를 올바르게 초기화하라
- C#/Effective C# 책 정리
- 2021. 5. 9. 19:19
참조
- Effective C# <강력한 C# 코드를 구현하는 50가지 전략과 기법, 이펙티브>, 빌 와그너, 김명신, 한빛미디어
- https://docs.microsoft.com/ko-kr/dotnet/csharp/programming-guide/classes-and-structs/static-constructors
소개
- 정적 멤버 변수를 포함하는 타입이 있다면 인스턴스를 생성하기 전에 반드시 정적 멤버 변수를 초기화해야 합니다.
- 이를 위해 C#에서는 정적 멤버 초기화 구문과 정적 생성자라는 두 가지 기능을 제공합니다.
정적 생성자
- 정적 생성자는 타입 내에 정의된 모든 메서드, 변수, 속성에 최초로 접근하기 전에 자동으로 호출되는 특이한 메서드입니다.
- 이 메서드를 활용하면 정적 변수를 초기화하거나, 싱글톤 패턴을 적용하거나, 혹은 여타의 작업을 효과적으로 수행할 수 있습니다.
- 정적 변수를 초기화하기 위해서 인스턴스 생성자나 전용의 private 메서드 혹은 다른 관용구를 사용해서는 안됩니다.
- 정적 필드를 초기화하는 과정이 매우 복잡하거나 혹은 상당한 자원(resource)을 소비하는 경우라면 Lazy
를 사용하여 해당 필드에 최초로 접근하는 시점까지 초기화 작업을 미룰 수 있습니다. - C#에서 정적 생성자를 사용하는 대표적인 사례중 하나가 싱글톤(Singleton) 패턴을 구현 하는 경우입니다.
public class MySingleton
{
private static readonly MySingleton theOneAndOnly = new MySingleton();
public static MySingleton TheOnly
{
get
{
return theOneAndOnly;
}
}
private MySingleton()
{
}
// 이하 생략
}
- 초기화 과정이 더 복잡한 경우라면 다음과 같이 정적 생성자를 사용하는 것도 좋은 방법입니다.
public class MySingleton2
{
private static readonly MySingleton2 theOneAndOnly;
static MySingleton2()
{
theOneAndOnly = new MySingleton2();
}
public static MySingleton2 TheOnly
{
get
{
return theOneAndOnly;
}
}
private MySingleton2()
{
}
// 이하 생략
}
정적 초기화 구문
- 인스턴스 멤버 초기화 구문과 마찬가지로 정적 멤버 초기화 구문 또한 정적 생성자가 호출되기 이전에 실행되며, 베이스 클래스의 정적 생성자보다도 먼저 호출됩니다.
- 모든 타입은 정적 생성자를 하나만 가질 수 있으며 어떠한 인자도 넘길 수 없습니다.
- 정적 생성자는 CLR에 의해서 호출되기 때문에 예외가 발생할 가능성이 있는 경우라면 매우 조심스럽게 다뤄야 합니다.
- 정적 생성자 내에서 예외가 발생하면 CLR은 TypeInitializationException 을 던지고 응용프로그램을 종료해 버립니다.
- 만약 호출하는 쪽에서 이 예외를 잡아버리면 상황은 더욱 복잡해집니다.
- 이 경우 해당 타입이 포함된 AppDomain을 언로드 하지 않는 한 이 타입으로 객체를 생성하지 못합니다.
- CLR이 정적 생성자를 호출하긴 하였지만, 해당 타입을 제대로 초기화하지는 못했다고 간주하기 때문입니다.
- 때문에, 정적 생성자를 이용할때는 try~catch 구문을 이용하여 작성해 주어야 합니다.
static MySingleton2()
{
try
{
theOneAndOnly = new MySingleton2();
}
catch
{
// 복구를 시도한다.
}
}
정리
- 정적 클래스 멤버를 초기화할 때 정적 생성자와 정적 초기화 구문을 사용할 수 있습니다.
- 간단하게 사용할 거면 정적 초기화 구문을 사용하고 예외 처리가 필요하거나 다양한 동작을 구현할 때 정적 생성자를 사용하는 것을 권장합니다.
728x90
'C# > Effective C# 책 정리' 카테고리의 다른 글
[Effective C# Item 5] 문화권별로 다른 문자열을 생성하려면 FormattableString을 사용하라. (0) | 2021.05.12 |
---|---|
[Effective C# Item 3] 캐스트 보다는 is,as가 좋다. (0) | 2021.05.11 |
[Effective C# item 1] 지역변수 선언은 var를 사용해라 (0) | 2021.05.10 |
[Effective C# Item 11] .NET 리소스 관리에 대한 이해 (0) | 2021.05.09 |
[Effective C# Item 9] 박싱과 언박싱을 최소화하라. (0) | 2021.05.09 |
이 글을 공유하기