如何从 ICollection<T> 中选择 IEnumerable<T> 而不是 List<T>?

Kon*_*ten 1 c# linq collections

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

Dictionary<Guid, List<T>> dictionary = source.ToDictionary(
  element => element.Id,
  element => element.Ts.ToList());
Run Code Online (Sandbox Code Playgroud)

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

Dictionary<Guid, IEnumerable<T>> dictionary = source.ToDictionary( ... );
Run Code Online (Sandbox Code Playgroud)

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

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

Mar*_*zek 5

那是因为Dictionary<TKey, TValue>不是协变的。所以你不能选择Dictionary<string, List<T>>并将其投射到Dictionary<string, IEnumerable<T>>即使List<T>Implements IEnumerable<T>。为什么?考虑以下代码:

Dictionary<string, IEnumerable<int>> myDict = new Dictionary<string, List<int>>();
myDict.Add("key", new HashSet<int>());
Run Code Online (Sandbox Code Playgroud)

从编译器的角度来看,这是完全可以的,因为HashSet<T>实现了IEnumerable<T>. 但字典期望的值是List<T>

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

Dictionary<Guid, IEnumerable<T>> dictionary = source.ToDictionary(
  element => element.Id,
  element => (IEnumerable<T>)element.Ts.ToList());
Run Code Online (Sandbox Code Playgroud)

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

Dictionary<Guid, IEnumerable<T>> dictionary = source.ToDictionary<Guid, IEnumerable<T>>(
  element => element.Id,
  element => element.Ts.ToList());
Run Code Online (Sandbox Code Playgroud)