【问题标题】:How to implicitly convert type 'System.Collections.Generic.Dictionary>' to 'System.Collections.Generic.IDictionary>'? [duplicate]如何将类型“System.Collections.Generic.Dictionary>”隐式转换为“System.Collections.Generic.IDictionary>”? [复制]
【发布时间】:2020-04-19 20:46:29
【问题描述】:

当我将 Dictionary<int, HashSet<int>> 分配给 IDictionary<int, IEnumerable<int>> 时,我收到以下错误:

编译错误(第 27 行,第 9 列):无法将类型“System.Collections.Generic.Dictionary>”隐式转换为“System.Collections.Generic.IDictionary>”。存在显式转换(您是否缺少演员表?)

错误很明显。缺少一个演员表。为什么我在这里需要演员表? Dictionary<T,U> 实现 IDictionary<T,U>HashSet<T> 实现 IEnumerable<T>

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

public class Program
{   
    public class A
    {
        public IDictionary<int, IEnumerable<int>> D { get; set; }
        public IEnumerable<int> H { get; set; }
    }

    public static void Main()
    {
        var hashSet = new HashSet<int>{1,2,1};
        var a = new A { H = hashSet };
        PrintCollection(a.H);

        var d = new Dictionary<int, HashSet<int>>{{ 3, hashSet  }};
        a.D = d; // error here
        PrintCollection(a.D.First().Value);
    }

    public static void PrintCollection(IEnumerable<int> collections)
    {
        foreach (var item in collections)
            Console.WriteLine(item);
    }
}

Try it Online!

【问题讨论】:

  • 我建议阅读 C# 中的方差。
  • 这是因为对于IDictionary&lt;TKey, TValue&gt;TValue 不是协变的。
  • 正如重复的 and Tom 的回答所解释的,您所问的内容不安全,因此被禁止。

标签: c# oop


【解决方案1】:

你不能。如果您采用 IDictionary&lt;int, IEnumerable&lt;int&gt;&gt; 类型的变量并尝试添加一个 IList&lt;int&gt; 作为值 - 根据变量的类型,您应该能够做到 - 那么在您的情况下,实际上需要添加一个无效成员你的Dictionary&lt;int, HashSet&lt;int&gt;&gt;。您不能强制转换此类型,因为这将使用类型系统说出不正确的内容 - 任何 IEnumerable&lt;int&gt; 都可以添加到字典中 - 它不能。

【讨论】:

    【解决方案2】:

    只有在安全的情况下才会选择加入 C# 中的变体。

    IEnumrable&lt;out T&gt; 支持协方差,但 IDictionary&lt;TKey, TValue&gt; 不支持。

    注意out 关键字;当类型通常为只读时允许协变赋值。

    现在想象如果IDictionary 是协变的:

    IDictionary<int, IEnumerable<int>> dict = new Dictionary<int, HashSet<int>>();
    dict.Add(1, new List<int>()); // oh dear, added a list to a Dictionary<int, HashSet<int>>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-13
      • 2022-12-07
      • 1970-01-01
      • 2012-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多