2013-04-24 4 views
4

메서드에 두 개의 오버로드가있는 경우 을 수락하고 IDictionary<TKey, TValue>을 수락하는 수식에 new Dictionary<string, int>()을 전달하면 모호한 것으로 간주됩니다. 그러나 두 가지 오버로드가 IEnumerableIEnumerable<KeyValuePair<TKey, TValue>>을 허용하도록 변경되면 호출이 더 이상 모호하지 않습니다. Dictionary<TKey, TValue>로서메소드에 IDictionary 및 IDictionary에 대한 오버로드가있는 경우 모호한 호출

은 (IEnumerable, IEnumerable<KeyValuePair<TKey, TValue>>, IReadOnlyCollection<KeyValuePair<TKey, TValue>>, IReadOnlyDictionary<TKey, TValue>, ICollection, IDictionary, ICollection<KeyValuePair<TKey, TValue>>, IDictionary<TKey, TValue> 정확한 것으로 .NET 4.5 ISerializable, IDeserializationCallback) 위의 모든 인터페이스를 구현; IDictionaryIEnumerable에서 상속 받고 IDictionary<TKey, TValue>IEnumerable<KeyValuePair<TKey, TValue>>에서 상속되므로 왜 그런지 이해할 수 없습니다.

샘플 콘솔 응용 프로그램 :

using System; 
using System.Collections; 
using System.Collections.Generic; 

namespace AmbigousCall 
{ 
    internal class Program 
    { 
     static void Main (string[] args) 
     { 
      var dic = new Dictionary<string, int>(); 
      FooDic(dic); // Error: The call is ambiguous 
      FooEnum(dic); // OK: The generic method is called 
      Console.ReadKey(); 
     } 

     static void FooDic (IDictionary dic) {} 
     static void FooDic<TKey, TValue> (IDictionary<TKey, TValue> dic) {} 
     static void FooEnum (IEnumerable dic) {} 
     static void FooEnum<TKey, TValue> (IEnumerable<KeyValuePair<TKey, TValue>> dic) {} 
    } 
} 

내가 오류는 다음과 같습니다 호출은 다음과 같은 방법 또는 속성 사이의 모호 'AmbigousCall.Program.FooDic (System.Collections.IDictionary)'와 'AmbigousCall .Program.FooDic (System.Collections.Generic.IDictionary) '

질문 1 : 왜 발생합니까?

질문 2 : 클래스가 둘 다 구현하는 경우 모호하지 않게 일반 및 일반이 아닌 인수를 모두 받아들이는 방법?

답변

6

C#은 사용 가능한 가장 구체적인 오버로드를 호출합니다. IEnumerable<T>IEnumerable까지 확장하므로 을 IEnumerable보다 구체적으로 식별하는 데 문제가 없습니다. 그러나 IDictionary<T, U>이 아니고IDictionary으로 확장되므로 Dictionary<T, U>이 모두 구현 되더라도 컴파일러는 더 구체적으로 식별 할 수 없습니다. 컴파일러에게 이것들은 전혀 관련이없는 인터페이스 일 수도 있습니다.

당신은 명시 적 캐스트를 사용하여 컴파일러에게 힌트를 제공해야 할 것 : IDictionary<TKey, TValue>IDictionary을 상속하지 않습니다 반면

FooDic((IDictionary)dic); // not ambiguous 
FooDic((IDictionary<string, int>)dic); // not ambiguous 
4

의 차이는, IEnumerable<T>IEnumerable을 상속한다는 것입니다. 두 인터페이스가 관련되지 않기 때문에 IDictionaryIDictionary<TKey, TValue> 사이 해결 반면 IEnumerable<T>IEnumerable의 인수보다 구체적이거나보다 일반적인 버전과 일치하는지 여부를 판정하는 단순한 문제이다 수락 과부하 사이 해석 결과

은 불가능 .

당신이 IDictionaryIDictionary<TKey, TValue>을 받아 과부하가있는 경우, 당신은 당신이 원하는 유형에 인수를 캐스팅해야합니다 :

FooDic((IDictionary)value); 

또는

FooDic((IDictionary<TKey, TValue>)value);