방프리
21.03.27 Chapter3. 제네릭 활용 (Item 24) 본문
Item 24 : 베이스 클래스나 인터페이스에 대해서 제네릭을 특화하지 말라
제네릭 클래스나 제네릭 메서드를 작성할 때는 사용자가 가능한 한 안전하고 혼란스럽지 않게 작성해야야한다.
특히 오버로드된 메서드가 여러 개인 경우, 컴파일러가 어떤 메서드를 선택하는지 정확히 알아야한다.
다음 예제를 통해서 어떤 메서드를 우선으로 호출하는지 확인해볼 수 있다.
using static System.Console;
public class MyBase
{
}
public interface IMessageWriter
{
void WriteMessage();
}
public class MyDerived : MyBase, IMessageWriter
{
void IMessageWriter.WriteMessage() =>
WriteLine("Inside MyDerived.WriteMessage");
}
public class AnotherType : IMessageWriter
{
public void WriteMessage() =>
WriteLine("Inside AnotherType.WriteMessage");
}
class Program
{
static void WriteMessage(MyBase b)
{
WriteLine("Inside WriteMessage(MyBase)");
}
static void WriteMessage<T>(T obj)
{
Write("Inside WriteMessage<T>(T): ");
WriteLine(obj.ToString());
}
static void WriteMessage(IMessageWriter obj)
{
Write("Inside WriteMessage(IMessageWriter): ");
obj.WriteMessage();
}
static void Main(string[] args)
{
MyDerived d = new MyDerived();
WriteLine("Calling Program.WriteMessage");
WriteMessage(d);
WriteLine();
WriteLine("Calling through IMessageWriter interface");
WriteMessage((IMessageWriter)d);
WriteLine();
WriteLine("Case to base object");
WriteMessage((MyBase)d);
WriteLine();
WriteLine("Another Type test: ");
AnotherType anObject = new AnotherType();
WriteMessage(anObject);
WriteLine();
WriteLine("Cast to IMessageWriter:");
WriteMessage((IMessageWriter)anObject);
}
}
위의 코드는 다음의 결과를 나타낸다.
Calling Program.WriteMessage
Inside WriteMessage<T>(T): Item14.MyDerived
Calling through IMessageWriter interface Inside
WriteMessage(IMessageWriter): Inside MyDerived.WriteMessage
Cast to base object
Inside WriteMessage(MyBase)
Another Type test:
Inside WriteMessage<T>(T): Item14.AnotherType
Cast to IMessageWriter:
Inside WriteMessage(IMessageWriter): Inside AnotherType.WriteMessage
첫 번째 테스트는 MyBase를 상속한 MyDerived 클래스는 WriteMessage(MyBase b)보다 WriteMessage<T>(T obj)가
더 정확히 일치힌다. 타입 매개변수인 T를 MyDerived로 대체하면 컴파일러 입장에서는 정확히 일치하는 메서드를
찾을 수 있기 때문이다.
두 번째, 세 번째는 명시적 형변환이 메서드 확인 규칙에 어떤 영향을 미치는지 보여준다.
네 번째와 마지막 테스트는 특정 인터페이스를 구현하고 있는 타입을 사용할 경우 어떤 메서드가 선택되는지
확인할 수 있다.
제네릭 타입을 이용한 오버로드 메서드를 사용할 때 위의 네 가지 규칙을 정확히 인지 후 사용해야
실수를 방지할 수 있다.
'C# > Effective C#' 카테고리의 다른 글
21.03.30 Chapter3. 제네릭 활용 (Item 26) (0) | 2021.03.30 |
---|---|
21.03.28 Chapter3. 제네릭 활용 (Item 25) (0) | 2021.03.28 |
21.03.14 Chapter3. 제네릭 활용 (Item 23) (0) | 2021.03.14 |
21.03.07 Chapter3. 제네릭 활용 (Item 22) (0) | 2021.03.07 |
21.02.07 Chapter3. 제네릭 활용 (Item 21) (0) | 2021.02.07 |
Comments