과부하, 일반 유형 추론 및 '매개 변수'키워드
-
10-07-2019 - |
문제
방금 과부하 분해능으로 이상한 동작을 발견했습니다.
다음 방법이 있다고 가정합니다.
public static void DoSomething<T>(IEnumerable<T> items)
{
// Whatever
// For debugging
Console.WriteLine("DoSomething<T>(IEnumerable<T> items)");
}
이제이 방법은 종종 소수의 명백한 주장으로 호출 될 것이라는 것을 알고 있습니다. 편의를 위해이 과부하를 추가합니다.
public static void DoSomething<T>(params T[] items)
{
// Whatever
// For debugging
Console.WriteLine("DoSomething<T>(params T[] items)");
}
이제이 방법을 호출하려고합니다.
var items = new List<string> { "foo", "bar" };
DoSomething(items);
DoSomething("foo", "bar");
그러나 두 경우 모두 과부하가 발생합니다 params
호출됩니다. 나는 예상했을 것이다 IEnumerable<T>
a List<T>
, 그것은 더 나은 일치처럼 보이기 때문에 (적어도 나에게).
이 행동은 정상입니까? 누구든지 설명 할 수 있습니까? MSDN 문서에서 그 정보에 대한 명확한 정보를 찾을 수 없었습니다 ... 여기에 관련된 과부하 해결 규칙은 무엇입니까?
해결책
C# 3.0 사양의 섹션 7.4.3은 여기에서 관련 비트입니다. 기본적으로 매개 변수 배열이 확장되었으므로 비교하고 있습니다.
public static void DoSomething<T>(T item)
그리고
public static void DoSomething<T>(IEnumerable<T> item)
그만큼 T
첫 경기는 BE로 추론됩니다 List<string>
그리고 T
두 번째 경기는 BE로 추론됩니다 string
.
이제 파라미터 유형으로의 인수에 대한 변환을 고려하십시오 - 첫 번째에서는 List<string>
에게 List<string>
; 두 번째로 List<string>
에게 IEnumerable<string>
. 첫 번째 변환은 7.4.3.4의 규칙에 따라 두 번째 변환보다 낫습니다.
반 직관적 인 비트는 유형의 추론입니다. 방정식에서 꺼내면 예상대로 작동합니다.
var items = new List<string> { "foo", "bar" };
DoSomething<string>(items);
DoSomething<string>("foo", "bar");
이 시점에는 각 호출에 해당 기능 구성원이 하나뿐입니다.
제휴하지 않습니다 StackOverflow