방프리

23.06.20 Chapter2. API 설계 (Item 19) 본문

C#/More Effective C#

23.06.20 Chapter2. API 설계 (Item 19)

방프리 2023. 7. 15. 19:38

Item 19 : 베이스 클래스에 정의된 메서드를 오버로드해서는 안 된다.

 

베이스 클래스와 파생 클래스 간에 오버로딩이 미치는 영향은 매개변수의 타입에 영향을 받는다. 즉 어떤 매개변수를

전달하느냐에 따라 예상치 못한 결과가 나올 수 있다.

오버로드는 다음과 같은 규칙을 가지고 있다.

 

1. 컴파일 타임상 상속 계통의 가장 아래쪽에 위치한 클래스의 메서드가 호출 가능한 메서드가 있는 경우 해당 메서드 선택

2. 런타임 타입이 파생 클래스일지라도 컴파일타임 타입이 베이스 클래스라면 베이스 클래스의 메서드 호출

3. 제네릭 방식의 매개변수를 추가할 경우 C# 버전에 따라 다른 결과를 도출

public class Animal
{
    public void Foo(Apple parm) => WriteLine("In Animal.Foo");
    
    public void Bar(Fruit parm) => WriteLine("In Animal.Foo");
    
    public void Baz(IEnumerable<Apple> parm) =>
    	WriteLine("In Animal.Foo2);
}

public class Tiger : Animal
{
	public void Foo(Fruit parm) => WriteLine("In Tiger.Foo");
   
	public void Bar(Fruit parm1, Fruit parm2 = null) =>
    	WriteLine("In Tiger.Foo2);
}


void Main()
{
     var sequence = new List<Apple> { new Apple(), new Apple() };
     var obj2 = new Tiger();
     obj2.Baz(sequence);
}

// C# 4.0 이하의 경우
제네릭 변형 지원하지 않으므로 Animal.Foo2() 호출

// C# 4.0 이상의 경우
제네릭 인터페이스가 공변셩과 반공변성 지원
Tiger.Foo2() 호출

이와 같이 환경 등에 따라 서로 다른 결과를 도출하기 때문에 베이스 클래스의 메서드를 오버로드하여 사용하지 말자.

Comments