728x90
반응형
12. 생성자에서 필드를 초기화하지 말고, 필드 선언부에서 바로 초기화 하라.
public class Customer
{
private List<Order> _orders;
public Customer()
{
_orders = new List<Order>(); // 생성자에서 초기화
}
}
// 추천
public class Customer
{
private List<Order> _orders = new List<Order>(); // 선언과 동시에 초기화
public string Name { get; set; } = "Unknown";
}
이유 | 설명 |
코드 간결성 | 생성자에 중복된 초기화 코드 줄어듦 |
가독성 향상 | 각 필드가 어떤 기본값을 갖는지 바로 보임 |
일관성 유지 | 모든 생성자에서 누락 없이 동일한 값으로 초기화됨 |
생성자 오버로드 시 편리 | 여러 생성자에 초기화 중복을 피할 수 있음 |
13. 정직 필드/속성은 선언시점에 초기화하거나 정적 생성자 (static constructor)를 명확히 활용하라.
초기화 순서를 잘못다루면 NullReferenceException, 예기치 모한 동작, 타입 초기화 순환 문제 등이 발생할 수 있다.
이유 | 설명 |
정확한 초기화 순서 보장 | static 생성자나 선언 초기화는 .NET이 타입 로드 시점에 딱 한 번 호출 |
스레드 안전성 확보 | 정적 생성자는 CLR이 자동으로 동기화 처리 |
명확한 책임 분리 | 초기화 코드가 흩어지지 않고 명확히 관리됨 |
불필요한 오버헤드 방지 | 잘못된 지연 초기화나 복잡한 조건식이 줄어듦 |
주의할 점
정적 생성자는 오직 한 번만 호출됨 | 여러 번 호출될 것처럼 착각하면 안 됨 |
타입 초기화 순환 주의 | A 타입의 static 멤버가 B 타입을 참조하고, B 타입 static이 다시 A를 참조하면 예외 발생 가능 |
예외 발생 시 타입 로드 실패 | static 생성자에서 예외가 발생하면, 해당 타입은 앱 도는 동안 다시 사용할 수 없음 (TypeInitializationException) |
14. 중복된 초기화 로직을 여러번 작성하지 말고 한 곳에만 두도록 하라
// 잘못된 예. Age가 여러 곳에서 초기화 되고 있다.
public class User
{
public string Name;
public int Age;
public User()
{
Name = "Unknown";
Age = 0;
}
public User(string name)
{
Name = name;
Age = 0;
}
public User(string name, int age)
{
Name = name;
Age = age;
}
}
//개선된 예
public class User
{
public string Name;
public int Age;
public User() : this("Unknown", 0) { }
public User(string name) : this(name, 0) { }
public User(string name, int age)
{
Name = name;
Age = age;
}
}
15. 리소스를 정리할 때는 using 문이나 try / finally 블록을 활용하라.
여기서 얘기하는 리소스는?
- FileStream, SqlConnection, StreamReader 등 메모리 외부 자원 (파일, 네트워크, DB 등)
- 이런 리소스들은 사용후 반드시 해제 (cleanup)을 해줘야 리소스 누수를 방지할 수 있다.
- 이에 자동 또는 확실하게 해제할 수 있도록 using 이나 try / finally를 사용하라
using (var reader = new StreamReader("file.txt"))
{
string content = reader.ReadToEnd();
}
StreamReader reader = null;
try
{
reader = new StreamReader("file.txt");
string content = reader.ReadToEnd();
}
finally
{
if (reader != null)
reader.Dispose();
}
try 블록에서 예외가 발생해도 finally는 반드시 실행되므로 안전하게 리소스를 해제할 수 있다.
상황 | 권장 방식 |
일반적인 IDisposable 리소스 사용 | using 문 |
리소스를 조건적으로 열거나 복잡한 흐름 제어 필요 | try/finally |
'프로그래밍&IT > C# & Winfrom' 카테고리의 다른 글
[Effective C#] Ch3. 표현하는 디자인 (1) 타입 가시성, 인터페이스 활용하자, callback을 위해 delegate 활용 (2) | 2025.07.09 |
---|---|
[Effective C#] Ch2. .Net 리소스 관리 (2) 객체 생성 및 해제, 값 & 참조 형식, 불변값 (2) | 2025.07.08 |
[Effective C#] Ch1. C# 관용어구 (3) - query, 형변환 연산자, 선택적 매개변수, 작은함수 (3) | 2025.07.05 |
[Effective C#] Ch1. C# 관용어구 (2) - Equals , GetHashCode (0) | 2025.06.29 |
[Effective C#] Ch1. C# 관용어구 (1) (0) | 2025.06.29 |