2

我刚才遇到了这种奇怪的情况:我正在编辑一些看起来像这样的遗留代码:

Hashtable hashtable = GetHashtable();

for (int i = 0; i < hashtable.Count; i++)
{
    MyStruct myStruct = (MyStruct)hashtable[i];

    //more code
}

现在将其更改为foreach循环时:

var hashtable = GetHashtable();

foreach (var item in hashtable)
{
    var myStruct = (MyStruct)item;

    //more code
}

我曾假设行为会是一样的,但是,我明白了System.InvalidCastException: Specified cast is not valid.

这种不同行为的原因是什么?

4

2 回答 2

15

迭代 aHashtable不会迭代其值,而是将键值对作为DictionaryEntry对象进行迭代。

而是尝试迭代其.Values集合。

foreach (var item in hashtable.Values)
{
    var myStruct = (MyStruct)item;
}

由于您正在重构旧的遗留代码,因此如果可能,您还应该考虑使用泛型Dictionary<TKey, TValue>代替。它将利用struct值语义并避免装箱。


如果您想迭代DictionaryEntry对象,您可以这样做,但需要对其进行强制转换以及您的MyStruct

foreach (DictionaryEntry entry in hashtable)
{
    var myStruct = (MyStruct)entry.Value;
}

最后,还有 Linq 解决方案,但它可能不适用于您,因为这是遗留代码;它可能不可用:

foreach(var myStruct in hashtable.Values.Cast<MyStruct>())
{

}
于 2013-07-22T12:30:34.023 回答
1

Hashtable 中的每个产生的项目都是一个 DictionaryEntry。因此你也可以这样做

foreach (DictionaryEntry de in hashtable)
{
    var myStruct = (MyStruct)de.Value;
    //more code
}
于 2013-07-22T12:39:09.800 回答