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.
这种不同行为的原因是什么?
迭代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
}