将通用字典<> 转换为 ICollection<> 问题

Posted

技术标签:

【中文标题】将通用字典<> 转换为 ICollection<> 问题【英文标题】:Converting Generic Dictionnary<> to ICollection<> problem 【发布时间】:2009-12-04 15:59:05 【问题描述】:

这里是一个例子:

public class ScheduleArea : IArea<Schedule>

//....
private Dictionary<int, ScheduleArea> subArea;
//.... 

#region IArea<Schedule> Members

public ICollection<KeyValuePair<int, IArea<Schedule>>> SubArea

     get 
        return (Collection<KeyValuePair<int, IArea<Schedule>>>)this.subArea;//Error here
     



#endregion

subArea 包含一个实际上是 IArea 的 ScheduleArea。为什么转换不起作用,我该如何解决?

【问题讨论】:

【参考方案1】:

它不起作用,因为您假设通用方差,直到 .NET 4.0 才起作用。

最简单的方法是手动进行(鉴于“c#2.0”标签,我假设您不能使用 LINQ):

List<KeyValuePair<int, IArea<Schedule>>> list = new
    List<KeyValuePair<int, IArea<Schedule>>>(subArea.Count);
foreach (KeyValuePair<int, ScheduleArea> pair in subArea)

    list.Add(new KeyValuePair<int, IArea<Schedule>>(pair.Key, pair.Value);

return list;

考虑到正在进行的复制量,我会将其设为方法而不是属性。

【讨论】:

乔恩:一个小小的挑剔:Dictionary&lt;K,V&gt; 确实实现了ICollection&lt;KeyValuePair&lt;K,V&gt;&gt; bit.ly/6NMnTV 这是 Dictionary 确实实现了 ICollection> 的证明 但不是Collection&lt;KeyValuePair&lt;K,V&gt;&gt;【参考方案2】:

您遇到了非常流行的泛型协方差问题。您基本上是在尝试将Dictionary&lt;int, ScheduleArea&gt; 转换为Dictionary&lt;int, IArea&lt;Schedule&gt;&gt;。 .NET 中的泛型不能这样分配

但是,您可以将其转换为IDictionary&lt;int, ScheduleArea&gt;ICollection&lt;KeyValuePair&lt;int, ScheduleArea&gt;&gt;。要真正获得ICollection&lt;KeyValuePair&lt;int, IArea&lt;Schedule&gt;&gt;,您需要更改subArea 变量类型或创建一个新字典:

Dictionary<int, IArea<Schedule>> dict = new Dictionary<int, IArea<Schedule>>(subArea.Count);

foreach (KeyValuePair<int, ScheduleArea> kvp in subArea) 

    dict.Add(kvp.Key, kvp.Value);


return dict;

另外,Dictionary 不会继承 Collection - 您需要改用 ICollection

【讨论】:

C# 2 - 没有可用的 var。我还建议,如果不再需要散列,我会使用 List 而不是 Dictionary 来获取新集合。【参考方案3】:

啊,关于协方差的日常问题。

见:Why can't I pass List<Customer> as a parameter to a method that accepts List<object>?

Convert List<DerivedClass> to List<BaseClass>

总结:每个项目都必须转换为新集合的新 KeyValuePair。

【讨论】:

以上是关于将通用字典<> 转换为 ICollection<> 问题的主要内容,如果未能解决你的问题,请参考以下文章

将字典转换为 List<KeyValuePair>

如何将 XML 转换为字典

将模板函数转换为通用 lambda

将 DataTable 转换为通用列表?

如何将 XML 字符串转换为字典?

如何将通用 List<T> 转换为基于接口的 List<T>