for循环和foreach循环之间的结构强制转换行为不同

本文关键字:循环 换行 转换 结构 foreach 之间 for | 更新日期: 2023-09-27 18:24:09

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

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.

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

for循环和foreach循环之间的结构强制转换行为不同

迭代Hashtable不会迭代其值,而是将键值对作为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>())
{
}

哈希表中的每个生成项都是DictionaryEntry。因此,你也可以这样做

foreach (DictionaryEntry de in hashtable)
{
    var myStruct = (MyStruct)de.Value;
    //more code
}