将Hashtable的Keys转换为List<int>或其他IEnumerable<int>?

11

我知道,我有其他的选项,例如我可以维护一个单独的键列表。请不要建议其他选项。 我只是想知道是否能够完成这个。 请不要问我要解决的问题是什么,或者类似的任何问题。 这是一个纯粹且简单的计算机科学问题。

我想知道是否有人知道一种将Hashtable中的键转换为List<int>或其他类型的IEnumerable<int>的方法(假设我的键实际上是整数)。

考虑到我可以毫不费力地执行此操作:

foreach (int key in hashtable.Keys)

为什么这会给我错误提示?

(List<int>)hashtable.Keys
6个回答

24

如果你有LINQ扩展方法可用,你可以这样做...

List<int> keys = hashtable.Keys.Cast<int>().ToList();

同样

List<int> keys = hashtable.Keys.OfType<int>().ToList();

根据自动装箱可能会起作用。


1
具体原因是Keys是一个ICollection,它只实现了IEnumerable而没有实现IEnumerable<T> - Adam Robinson
1
还要注意,由于OP要求“其他IEnumerable<int>”,因此您可以放弃使用ToList,只需将变量类型设置为IEnumerable<int>(或var)。 - Adam Robinson
@Adam Robinson,说得好!而且感谢你添加了解释。我现在的连接很差,编辑我的答案有点困难,所以我建议OP参考你的评论获取更多信息。 - Quintin Robinson
谢谢!我误解了Cast<T>()方法的描述。由于某种原因,我认为类型参数应该是集合的类型而不是元素的类型。这是我的错,没有好好阅读! :) - Samo

4

因为foreach需要hashtable.Keys是一个IEnumerable<TKey>,而它确实如此。然而,hashtable.Keys不是List<TKey>;它只是一个简单的ICollection,这是不同的。要将其转换为List,请尝试使用一些Linq:

List<int> keys = hashtable.Keys.OfType<int>().ToList();

这将基本上枚举Keys集合并将每个元素添加到一个新的List中,然后给你List。OfType()比Cast更“安全”;Cast只尝试将整个集合视为IEnumerable<int>,如果任何包含的元素为null或无法隐式转换为整数,则可能导致运行时错误或不可预测的行为。相比之下,OfType将遍历源并生成一个仅包含实际为int的元素的可枚举对象。如果您确定所有键都是整数,则任何一种方法都可以使用。


foreach 需要 IEnumerable,而非 IEnumerable<T> - Adam Robinson
从技术上讲,是的。但如果该可枚举对象是强类型的,则需要将项变量定义为该类型(或可以隐式转换为该类型);如果您尝试执行类似foreach(int id in MyCollectionOfReferenceTypes)的操作,编译器会报错。 - KeithS

0

因为hashtable.Keys是一个对象集合,它与整数列表不是协变的。


1
如果我们要挑刺的话,协方差并不是必需的;可转换性才是。 - Adam Robinson

0

你可以这样做:ICollection<int> keyCols = hashtable.Keys;


0

-1

你的 foreach 循环如果 Keys 集合不包含 int 就会抛出一个 InvalidCastException 异常。

转换为 List<int> 调用失败,因为编译器无法将非泛型的 ICollection 转换为特定的 ICollection<T>


转换失败是因为Keys不是可以像List一样使用的类型;它是ICollection,这是一个非常基本的接口,不会公开List可用的方法。 - KeithS

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接