다음 본문은 도서 이펙티브 C# (빌 와그너)에서 나오는 주제를 다룹니다.
제약조건은 타입 매개변수가 할 수 있는 것을 규정하지만, 무엇을 해서는 안 되는지는 규정하지 않는다.
제약조건이 요구하는 작업 외에는 신경을 쓰지 않는다는 것이다.
하지만 IDisposable을 구현하고 있다면 추가 작업이 필요하다.
메소드 내에서 타입 객체를 생성한 경우
- T가 IDisposable을 구현한 타입일경우 그냥 생성하고 사용하기만하면 리소스 누수가 발생할 수 있다.
- T가 IDisposable을 구현했다면 using 블록이 끝날 때 Dispose()를 호출한다.
public void GetThingsDone()
{
T driver = new T();
using(driver as IDisposable)
{
diriver.DoWork();
}
}
클래스 내의 멤버로 타입 객체를 선언한경우
- T가 IDisposable을 구현했을 가능성이 있다면 클래스 내에서 IDisposable을 구현하여 해당 리소스를 처리해야한다.
public sealed class EngineDriver2<T> : IDisposable where T : IEngine, new()
{
private Lazy<T> driver = new Lazy<T>(() => new T());
public void GetThingsDone() => driver.Value.Dowork();
public void Dispose()
{
if(driver.IsValueCreated)
{
var resource = driver.Value as IDisposable;
resource?.Dispose();
}
}
}
- 제네릭 클래스의 코드가 복잡해 지는 것을 원하지 않는다면, 객체의 소유권과 Dispose의 호출책임을 외부로 넘겨 new() 제약조건을 제거할 수 있다.
public sealsed class EngineDriver<T> where T : IEngine
{
private T driver;
public EngineDriver(T driver)
{
this.driver = driver;
}
public void GetThingsDone()
{
driver.DoWork();
}
}
결론
- 타입 매개변수를 사용하는 경우 리소스가 누수되지않도록 주의하자.
'🌍 C# Study > 이펙티브 C#' 카테고리의 다른 글
[23] 타입 매개변수에 대해 메서드 제약 조건을 설정하려면 델리게이트를 활용하라 (0) | 2021.04.27 |
---|---|
[22] 공변성과 반공변성을 지원하라 (0) | 2021.04.27 |
[20] IComparable<T>와 IComparer<T>를 이용하여 객체의 선후 관계를 정의하라 (0) | 2021.04.26 |
[19] 런타임에 타입을 확인하여 최적의 알고리즘을 사용하라 (0) | 2021.04.26 |
[18] 반드시 필요한 제약조건만 설정하라 (0) | 2021.04.26 |