【问题标题】:Does `Dictionary<TKey, TValue>.KeyCollection` implement `IReadOnlyCollection` or not?`Dictionary<TKey, TValue>.KeyCollection` 是否实现了 `IReadOnlyCollection`?
【发布时间】:2015-01-29 15:42:15
【问题描述】:

这个问题看起来很简单。虽然documentation 说是这样:

public sealed class KeyCollection : ICollection<TKey>, 
    IReadOnlyCollection<TKey>, IEnumerable<TKey>, ICollection, IEnumerable

以下代码给出错误:

class MyKeys<T>
{
    readonly Dictionary<T, T> dict = new Dictionary<T, T> ();
    public IReadOnlyCollection<T> Keys { get { return dict.Keys; } set; }
}

表示没有从KeyCollection&lt;T&gt;IReadOnlyCollection&lt;T&gt; 的转换。

此外,polish documentation(同样是法语)说它没有:

[SerializableAttribute]
public sealed class KeyCollection : ICollection<TKey>, 
    IEnumerable<TKey>, ICollection, IEnumerable

这是什么?

如果是英文文档中的错误,还有一个额外的问题:

有没有办法将Keys 设为只读集合?

【问题讨论】:

  • 虽然它没有实现IReadOnlyCollection&lt;TKey&gt;,但它是只读的,因为IsReadOnly返回true,AddRemoveClear都抛出异常。
  • 我一直想知道为什么Dictionary&lt;TKey, TValue&gt;.KeyCollection没有实现ISet&lt;TKey&gt;...

标签: c# .net dictionary


【解决方案1】:

Dictionary.KeyCollection 目前没有实现IReadOnlyCollection

不过,该接口已添加到下一个版本的 .Net (v4.6) 中。使用 VS 2015 预览版可以看到。

您还可以在this announcement 中看到(下载包含 v4.6 的所有更改的 excel 文件)

【讨论】:

  • 哦,所以英文文档可能是最新的。
  • @luk32 如果您将版本从 4.5 更改为更低的版本,它确实表明它没有实现 IReadOnlyCollection
  • @luk32 如果是这种情况(错误地),我实际上不会感到惊讶
【解决方案2】:

在撰写此答案时,reference source 不包含 IReadOnlyCollection 交互实现:

public sealed class KeyCollection: ICollection<TKey>, ICollection

从那时起,参考源已更新为现在包含 IReadOnlyCollection 接口。

public sealed class KeyCollection: ICollection<TKey>, ICollection, IReadOnlyCollection<TKey>

【讨论】:

  • 请注意,上面的参考源链接现在指的是更新后的 .NET 代码,其中 KeyCollection 确实派生自 IReadOnlyCollection
  • 谢谢。我更新了答案以反映参考源现在具有接口。
【解决方案3】:

您指的是 .Net framework 4.5 的文档。在哪里添加。 source code

public sealed class KeyCollection: ICollection<TKey>, ICollection

如果您查看documentation for .Net framework 4.0,那么它有:

public sealed class KeyCollection : ICollection<TKey>, 
    IEnumerable<TKey>, ICollection, IEnumerable

其中ICollection&lt;TKey&gt; implements IEnumerable&lt;T&gt;ICollection 实现IEnumerable,因此没有实现IReadOnlyCollection&lt;TKey&gt;

有没有办法将 Keys 设为只读集合?

你可以这样做:

ReadOnlyCollection<int> readonlyKeys = new ReadOnlyCollection<int>(dictionary.Keys.ToList());

【讨论】:

  • 我会说它是Keys副本作为只读集合,而不是原始Keys 包装或转换。原始容器将被复制。我错了吗?
  • @luk32,是的,你是对的。如果您使用 Visual Studio 2015 并指定 .Net 框架版本 .Net 4.6,那么您可以这样做 IReadOnlyCollection&lt;int&gt; Keys = dictionary.Keys;
  • 对于任何未来的读者,请注意上述答案中指向 .NET 源代码的链接指向更新版本 (4.6),它确实派生自 IReadOnlyCollection,但 .NET 4.5版本最初没有包含它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-09
  • 2016-06-14
  • 2011-04-11
  • 1970-01-01
  • 2011-01-16
相关资源
最近更新 更多