2016-09-21 1 views
1

과부하 해결에 대한 질문이 있습니다. 유형의 매개 변수 person을 허용하는 제한된 일반 메서드 Greet이 있고 Person에서 파생되어야한다고 가정합니다. 이 Greet 메서드는 person을 매개 변수로 전달하는 다른 클래스의 일부 비 제너릭 메서드를 호출합니다. 비 제네릭 메서드에는 기본 클래스 및 파생 클래스에 대한 여러 가지 오버로드가 있습니다. 기본 클래스의 오버로드가 항상 호출되는 이유는 무엇입니까?이상한 메서드 오버로드 해결 제한된 일반 인수 : 기본 클래스 arg가 항상 호출 된 오버로드

예 :

public static class Test 
{ 
    public static void Greet() 
    { 
    new SomeClass().Greet(new Person()); // Hi, I am a Person 
    new SomeClass().Greet(new Manager()); // Hi, I am a Person -- Why? 
    } 
} 
public class SomeClass 
{  
    public void Greet<T>(T person) where T : Person 
    { 
    new Greeter().SayHi(person); 
    } 
} 
public class Person { /* some props and methods */ } 
public class Manager : Person { /* some props and methods */ } 
public class Greeter 
{ 
    public SayHi(Person person) { Console.WriteLine("Hi, I am a person"); } 
    public SayHi(Manager person) { Console.WriteLine("Hi, I am a manager"); } 
} 

그러나, 사람을 받아들이에만 SayHi 항상라고합니다. 왜?

+1

외부에서 '동적'을 사용하면 과부하 해결은 * 런타임 *이 아닌 컴파일 타임 *에서 수행됩니다. 호출을 컴파일하려면 하나의 메소드를 선택해야합니다. –

답변

3

컴파일러는 그 시점에서

new Greeter().SayHi(person); 

의 호출에 대한 오버로드 확인을 수행 할 수 있으며, person의 종류는 알고있는 모든이 TPerson에 암시 적으로 변환 있다는 것이다 단지 T입니다. 따라서 Greeter의 유일한 적용 가능한 방법은 SayHi(Person)입니다.

컴파일 타임에 한 번 발생합니다. 실행 시간에 T에 사용되는 각 유형 인수에 대해 별도로 발생하지 않습니다.

+0

에는 동일한 의도를 구현하는 추악한 패턴이 있습니다 (매개 변수의 유형을 검사하는'if' 명령문을 사용하지 않고) – AunAun

+1

@AunAun :'Greet'를'Greeter '대신'Person'에서 가상 메소드로 만듭니다 '또는'dynamic'을 사용하십시오 ... –

관련 문제