[英]How to pick IEnumerable<T> instead of List<T> from an ICollection<T>?
I have the following lines that work as supposed to. 我有以下几行按预期工作。
Dictionary<Guid, List<T>> dictionary = source.ToDictionary(
element => element.Id,
element => element.Ts.ToList());
However, I'd like the first line to use IEnumerable , which creates an error of type mismatch. 但是,我希望第一行使用IEnumerable ,这会产生类型不匹配的错误。
Dictionary<Guid, IEnumerable<T>> dictionary = source.ToDictionary( ... );
Using ToArray instead of ToList won't help me (getting the same error, plus I've learned not to use arrays in C# unless really, really required) And as far I can tell, the type of Ts is ICollection . 使用ToArray而不是ToList不会对我有帮助(出现相同的错误,另外,我知道除非真的非常需要,否则我不会在C#中使用数组)据我所知, Ts的类型是ICollection 。
Is it possible to convert the whole shabang the way I wish without going hardcore and using casting? 是否可以按照我希望的方式转换整个shabang,而无需进行硬核转换和使用强制转换?
That's because Dictionary<TKey, TValue>
is not covariant. 这是因为
Dictionary<TKey, TValue>
不是协变的。 So you can't pick Dictionary<string, List<T>>
and cast it to Dictionary<string, IEnumerable<T>>
even though List<T>
implements IEnumerable<T>
. 因此
Dictionary<string, IEnumerable<T>>
即使List<T>
实现IEnumerable<T>
Dictionary<string, List<T>>
您也不能选择Dictionary<string, List<T>>
并将其转换为Dictionary<string, IEnumerable<T>>
。 Why? 为什么? Consider following code:
考虑以下代码:
Dictionary<string, IEnumerable<int>> myDict = new Dictionary<string, List<int>>();
myDict.Add("key", new HashSet<int>());
From compiler perspective that would be totally ok, because HashSet<T>
implements IEnumerable<T>
. 从编译器的角度来看,这是完全可以的,因为
HashSet<T>
实现了IEnumerable<T>
。 But the dictionary is expecting the value to be List<T>
! 但是字典期望值是
List<T>
!
You can do a cast in ToDictionary
method: 您可以使用
ToDictionary
方法进行ToDictionary
:
Dictionary<Guid, IEnumerable<T>> dictionary = source.ToDictionary(
element => element.Id,
element => (IEnumerable<T>)element.Ts.ToList());
or provide generic type parameters to ToDictionary
call: 或为
ToDictionary
调用提供通用类型参数:
Dictionary<Guid, IEnumerable<T>> dictionary = source.ToDictionary<Guid, IEnumerable<T>>(
element => element.Id,
element => element.Ts.ToList());
Use AsEnumerable()
, which is a handy Linq method that just returns the source cast to IEnumerable<T>
: 使用
AsEnumerable()
,这是一个方便的Linq方法,该方法仅将源强制转换返回到IEnumerable<T>
:
Dictionary<Guid, IEnumerable<T>> dictionary = source.ToDictionary(
element => element.Id,
element => element.Ts.AsEnumerable());
you could also try casting: 您也可以尝试投射:
Dictionary<Guid, IEnumerable<T>> dictionary = source.ToDictionary(
element => element.Id,
element => (IEnumerable<T>)(element.Ts));
If you want to avoid casting, you can use the AsEnumerable
extension method, which would return the correct type, but also hide the original instance/implementation behind an anonymous enumerable. 如果要避免强制转换,可以使用
AsEnumerable
扩展方法,该方法将返回正确的类型,但也将原始实例/实现隐藏在匿名枚举后面。
I would personally just use element => element.Ts as IEnumerable<T>
though, to avoid calling extra method only to satisfy the limited generics inference. 我个人只是将
element => element.Ts as IEnumerable<T>
,以避免仅为了满足有限的泛型推断而调用额外的方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.