I came across this bizarre situation just now: I was editing some legacy code which looks something like this:
Hashtable hashtable = GetHashtable();
for (int i = 0; i < hashtable.Count; i++)
{
MyStruct myStruct = (MyStruct)hashtable[i];
//more code
}
Now when changing this to a foreach loop:
var hashtable = GetHashtable();
foreach (var item in hashtable)
{
var myStruct = (MyStruct)item;
//more code
}
I had assumed the behavior would be the same, however, I get System.InvalidCastException: Specified cast is not valid.
What is the reason for this different behavior?
Iterating a Hashtable doesn't iterate its values, rather it iterates key value pairs as a DictionaryEntry object.
Instead try iterating on its .Values collection instead.
foreach (var item in hashtable.Values)
{
var myStruct = (MyStruct)item;
}
Since you are refactoring old legacy code, if possible, you should also consider using the generic Dictionary<TKey, TValue> instead. It will take advantage of struct value semantics and avoid boxing.
If you wanted to iterate on the DictionaryEntry objects, you can do so but will need to cast to it as well as your MyStruct:
foreach (DictionaryEntry entry in hashtable)
{
var myStruct = (MyStruct)entry.Value;
}
Finally, there's the Linq solution, but it may not be applicable for you since this is legacy code; it may not be available:
foreach(var myStruct in hashtable.Values.Cast<MyStruct>())
{
}
Each yielded item in a Hashtable is a DictionaryEntry. Therefore you can also do it like this
foreach (DictionaryEntry de in hashtable)
{
var myStruct = (MyStruct)de.Value;
//more code
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With