2016-08-31 3 views
3

나는 다음과 같은 방법이 있습니다이 C# 메서드 오버로드가 예상대로 작동하지 않는 이유는 무엇입니까?

나는 다음과 같은 실행
public void Say<TItem>(TItem item) 
{ 
    Console.WriteLine("A"); 
} 

public void Say<TItem>(IEnumerable<TItem> items) 
{ 
    Console.WriteLine("B"); 
} 

:

void Main() 
{ 
    Say<string>("Foo"); 
    Say(new string[] { "Foo", "Bar"}); 

} 

첫 번째 방법은 두 번 호출됩니다

A 
A 

IEnumerable<T>TItem[]로 변경 참고 않습니다 예상대로 작동하지만 IEnumerable<T>의 경우 두 번째 방법을 선택하지 않는 이유는 무엇입니까? 의도 한 오버로드를 어떻게 달성 할 수 있습니까?

답변

6

TItemstring[].이라고 생각하기 때문에 컴파일러의 관점에서 보자.이 방법은 플러그 인하기 위해 제네릭 형식을 찾고 있다는 것만 알면된다. 문자열 []이 하나의 형식 일뿐입니다.

Say<string>(new string[]{"Foo", "Bar"}); 

는 당신이 실제로 원하는 방법을 선택 얻을 충분해야한다 : 여기에 의미가 잠재적으로 모호하기 때문에, 당신은 컴파일러에게 당신이 찾고있는 과부하를 선택할 수있는 몇 가지 도움을 줄 필요가있다.

+0

위와 같지만 매개 변수 유형이'IEnumerable '이 아닌'string [] '인 경우이 추가 도움말이 필요하지 않은 이유는 무엇입니까? – MaYaN

+1

@MaYaN 두 경우 모두 호출이 두 서명과 잠재적으로 일치 할 수 있습니다. 이 메소드가'IEnumerable'을 취할 때, 암시 적 캐스트가 필요하다. 다른 메소드는 그런 캐스트가 필요 없다. complier의 마음에, 그것은 첫 번째 과부하를 더 가깝게 만든다. 좀 더 구체적인 것을 얻으면 컴파일러는 당신이하려고했던 것을 더 잘 추론 할 수 있습니다. – pquest

관련 문제