首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >方法重载IDictionary和IDictionary<TKey、TValue>时的模糊调用

方法重载IDictionary和IDictionary<TKey、TValue>时的模糊调用
EN

Stack Overflow用户
提问于 2013-04-24 16:48:49
回答 2查看 990关注 0票数 8

当一个方法有两个重载(一个接受IDictionary,另一个接受IDictionary<TKey, TValue> )时,将new Dictionary<string, int>()传递给它被认为是矛盾的。但是,如果将这两个重载更改为接受IEnumerableIEnumerable<KeyValuePair<TKey, TValue>>,则调用不再具有矛盾性。

由于Dictionary<TKey, TValue>实现了上述所有接口(确切地说,IDictionary<TKey, TValue>ICollection<KeyValuePair<TKey, TValue>>IDictionaryICollectionIReadOnlyDictionary<TKey, TValue>IReadOnlyCollection<KeyValuePair<TKey, TValue>>IEnumerable<KeyValuePair<TKey, TValue>>IEnumerableISerializableIDeserializationCallback在.NET 4.5中);由于IDictionary是从IEnumerableIDictionary<TKey, TValue>继承而来的,所以我无法理解为什么会发生这种情况。

示例控制台应用程序:

代码语言:javascript
运行
复制
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:如果一个类实现了泛型和非泛型参数,那么如何在不引起歧义的情况下接受这两个参数?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-04-24 16:53:59

C#将调用可用的最特定的重载。它不难将IEnumerable<T>识别为比IEnumerable更具体,因为IEnumerable<T>扩展了IEnumerable。然而,IDictionary<T, U>并没有扩展IDictionary,因此即使Dictionary<T, U>实现了这两种功能,编译器也无法识别哪个更具体。对于编译器来说,这些可能是完全无关的接口。

您必须使用显式强制转换给编译器一个提示:

代码语言:javascript
运行
复制
FooDic((IDictionary)dic); // not ambiguous
FooDic((IDictionary<string, int>)dic); // not ambiguous
票数 9
EN

Stack Overflow用户

发布于 2013-04-24 16:55:06

区别在于IEnumerable<T>继承了IEnumerable,而IDictionary<TKey, TValue>没有继承IDictionary

因此,在接受IEnumerable<T>IEnumerable的重载之间进行解析是一个简单的问题,可以确定参数是匹配更具体的版本还是更一般的版本,而IDictionaryIDictionary<TKey, TValue>之间的解析是不可能的,因为这两个接口没有关联。

如果有接受IDictionaryIDictionary<TKey, TValue>的重载,则必须将参数转换为所需的类型:

代码语言:javascript
运行
复制
FooDic((IDictionary)value);

代码语言:javascript
运行
复制
FooDic((IDictionary<TKey, TValue>)value);
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16197715

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档