다음 본문은 도서 이펙티브 C# (빌 와그너)에서 나오는 주제를 다룹니다.
제네릭 컬렉션에서 타입을 구체화하는 경우 해당 타입의 기능들을 활용할 수 있다.
예를들어 IEnumerable<int>, IEnumerable<double>, IEnumerable<float> 등으로 타입 매개변수가 숫자인 경우에만 사용할 수 있는 확장 메서드들이 존재한다.
다음은 IEnumerable<int>에 특화된 확장 메서드 들 중 일부이다.
public static class Enumerable
{
public static int Average(this IEnumerable<int> squence);
public static int Max(this IEnumerable<int> sequence);
public static int Min(this IEnumerable<int> sequence);
public static int Sum(this IEnumerable<int> sequence);
....
}
확장 메서드 vs 파생 클래스의 메서드
전자 상거래 프로그램을 개발 중 고객에게 쿠폰을 발송하는 메서드를 만드는 경우를 생각해보자.
일반적인 구현방법은 다음과 같이 구체화된 제네릭 타입을 상속하여 클래스 메서드로 구현하는 것이다.
public class CustomerList : List<Customer>
{
public void SendEmailCoupons(Coupon specialOffer)
{
//...
}
}
확장 메서드를 활용하면 다음과 같이 구현할 수 있다.
public static void SendEmailCoupons(this IEnumerable<Customer> customers, Coupon specialOffer)
{
//...
}
확장 메서드는 IEnumerable<Customer>를 기반으로 작성되었지만,
상속으로 파생된 클래스에 메서드를 추가한 방식은 List<Customer>를 기반으로 한다.
결국 더 이상 이터레이터 메서드를 사용할 수 없다.
결론
- 기능을 추가할 때 구체화된 제네릭 필드를 상속하여 메서드를 추가하기 보다는 확장메서드를 구현하는 것을 고려하자
'🌍 C# Study > 이펙티브 C#' 카테고리의 다른 글
[30] 루프보다 쿼리 구문이 낫다 (0) | 2021.04.28 |
---|---|
[29] 컬렉션을 반환하기보다 이터레이터를 반환하는 것이 낫다 (0) | 2021.04.28 |
[27] 인터페이스는 간략히 정의하고 기능의 확장은 확장 메서드를 사용하라 (0) | 2021.04.28 |
[26] 제네릭 인터페이스와 논제네릭 인터페이스를 함께 구현하라 (0) | 2021.04.28 |
[25] 타입 매개변수로 인스턴스 필드를 만들 필요가 없다면 제네릭 메서드를 정의하라 (0) | 2021.04.27 |