当一个方法有两个重载(一个接受IDictionary,另一个接受IDictionary<TKey, TValue> )时,将new Dictionary<string, int>()传递给它被认为是矛盾的。但是,如果将这两个重载更改为接受IEnumerable和IEnumerable<KeyValuePair<TKey, TValue>>,则调用不再具有矛盾性。
由于Dictionary<TKey, TValue>实现了上述所有接口(确切地说,IDictionary<TKey, TValue>、ICollection<KeyValuePair<TKey, TValue>>、IDictionary、ICollection、IReadOnlyDictionary<TKey, TValue>、IReadOnlyCollection<KeyValuePair<TKey, TValue>>、IEnumerable<KeyValuePair<TKey, TValue>>、IEnumerable、ISerializable、IDeserializationCallback在.NET 4.5中);由于IDictionary是从IEnumerable和IDictionary<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:如果一个类实现了泛型和非泛型参数,那么如何在不引起歧义的情况下接受这两个参数?
发布于 2013-04-24 16:53:59
C#将调用可用的最特定的重载。它不难将IEnumerable<T>识别为比IEnumerable更具体,因为IEnumerable<T>扩展了IEnumerable。然而,IDictionary<T, U>并没有扩展IDictionary,因此即使Dictionary<T, U>实现了这两种功能,编译器也无法识别哪个更具体。对于编译器来说,这些可能是完全无关的接口。
您必须使用显式强制转换给编译器一个提示:
FooDic((IDictionary)dic); // not ambiguous
FooDic((IDictionary<string, int>)dic); // not ambiguous发布于 2013-04-24 16:55:06
区别在于IEnumerable<T>继承了IEnumerable,而IDictionary<TKey, TValue>没有继承IDictionary。
因此,在接受IEnumerable<T>和IEnumerable的重载之间进行解析是一个简单的问题,可以确定参数是匹配更具体的版本还是更一般的版本,而IDictionary和IDictionary<TKey, TValue>之间的解析是不可能的,因为这两个接口没有关联。
如果有接受IDictionary和IDictionary<TKey, TValue>的重载,则必须将参数转换为所需的类型:
FooDic((IDictionary)value);或
FooDic((IDictionary<TKey, TValue>)value);https://stackoverflow.com/questions/16197715
复制相似问题