for和foreach循环之间的结构铸造行为不同

时间:2013-07-22 12:28:33

标签: c#

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

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.

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

2 个答案:

答案 0 :(得分:15)

迭代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>())
{

}

答案 1 :(得分:1)

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

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