【问题标题】:How to pick IEnumerable<T> instead of List<T> from an ICollection<T>?如何从 ICollection<T> 中选择 IEnumerable<T> 而不是 List<T>?
【发布时间】:2015-07-14 22:11:15
【问题描述】:

我有以下几行按预期工作。

Dictionary<Guid, List<T>> dictionary = source.ToDictionary(
  element => element.Id,
  element => element.Ts.ToList());

但是,我希望第一行使用 IEnumerable,这会产生类型不匹配的错误。

Dictionary<Guid, IEnumerable<T>> dictionary = source.ToDictionary( ... );

使用 ToArray 而不是 ToList 对我没有帮助(得到同样的错误,而且我学会了不要在 C# 中使用数组,除非真的非常需要)据我所知,Ts 的类型是 ICollection

是否可以按照我希望的方式转换整个shabang,而无需硬核和使用铸造?

【问题讨论】:

    标签: c# linq collections


    【解决方案1】:

    那是因为Dictionary&lt;TKey, TValue&gt; 不是协变的。因此,即使List&lt;T&gt; 实现了IEnumerable&lt;T&gt;,您也不能选择Dictionary&lt;string, List&lt;T&gt;&gt; 并将其转换为Dictionary&lt;string, IEnumerable&lt;T&gt;&gt;。为什么?考虑以下代码:

    Dictionary<string, IEnumerable<int>> myDict = new Dictionary<string, List<int>>();
    myDict.Add("key", new HashSet<int>());
    

    从编译器的角度来看,这完全没问题,因为HashSet&lt;T&gt; 实现了IEnumerable&lt;T&gt;。但字典预计值为List&lt;T&gt;

    您可以在ToDictionary 方法中进行强制转换:

    Dictionary<Guid, IEnumerable<T>> dictionary = source.ToDictionary(
      element => element.Id,
      element => (IEnumerable<T>)element.Ts.ToList());
    

    或者提供泛型类型参数给ToDictionary调用:

    Dictionary<Guid, IEnumerable<T>> dictionary = source.ToDictionary<Guid, IEnumerable<T>>(
      element => element.Id,
      element => element.Ts.ToList());
    

    【讨论】:

    • 哈,我完全忘记了显式类型注释。那是我的赢家。
    【解决方案2】:

    使用AsEnumerable(),这是一种方便的Linq 方法,它只是将源转换返回到IEnumerable&lt;T&gt;

    Dictionary<Guid, IEnumerable<T>> dictionary = source.ToDictionary(
      element => element.Id,
      element => element.Ts.AsEnumerable());
    

    您也可以尝试投射:

    Dictionary<Guid, IEnumerable<T>> dictionary = source.ToDictionary(
      element => element.Id,
      element => (IEnumerable<T>)(element.Ts));
    

    【讨论】:

      【解决方案3】:

      如果您想避免强制转换,可以使用 AsEnumerable 扩展方法,该方法会返回正确的类型,但也会将原始实例/实现隐藏在匿名枚举后面。

      不过,我个人只会使用 element =&gt; element.Ts as IEnumerable&lt;T&gt;,以避免调用额外的方法来满足有限的泛型推断。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多