dim d as dictionary
d=new Dictionary
d.Value("theKey")="theValue"
for each p as pair in d
break
next
This code will compile. However, when run, it throws an IllegalCastException on the Next statement, because Dictionaries don’t iterate Pair objects, they contain DictionaryEntry objects.
However, this code will fail compilation:
dim numbers() as integer
for each b as boolean in numbers
break
next
Type mismatch on the For…Each line.
What’s the difference here? Seems like the Dictionary code should throw the type mismatch error during compilation. And if you change it to this, it does throw the correct error:
dim d as dictionary
d=new Dictionary
d.Value("theKey")="theValue"
for each i as integer in d
break
next
Is it perhaps becuase, internally, a DictionaryEntry is a subclass of Pair…?
So there is an internal DictionaryIterator class, which returns value as a variant, so you won’t get compile error for whatever you write there.
The thing you get is a DictionaryEntry.
And DictionaryEntry is not a pair, but its own class.
DictionaryEntryinherits from Pair, so the compiler allows the assignment.
At runtime, it tries to cast each DictionaryEntry to a Pair, and this is where it fails, because For Each in Xojo requires an exact match or a valid cast.
To iterate a Dictionary safely, always use:
for each entry as DictionaryEntry in d
dim key as variant = entry.Key
dim value as variant = entry.Value
next
Or, if you want the result as a Pair, cast manually inside the loop (with error handling if needed).
Here’s a short utility function in Xojo that takes a Dictionary and returns an array of Pair objects — one for each key/value entry:
Function DictionaryToPairs(d As Dictionary) As Pair()
Dim result() As Pair
For Each entry As DictionaryEntry In d
result.Add(entry.Key : entry.Value) ' Create Pair using colon syntax
Next
Return result
End Function
Usage Example:
Dim d As New Dictionary
d.Value("Name") = "Sascha"
d.Value("Role") = "Developer"
Dim pairs() As Pair = DictionaryToPairs(d)
For Each p As Pair In pairs
System.DebugLog(p.Left.StringValue + " = " + p.Right.StringValue)
Next
I don’t think this is quite the case, because the compiler won’t let you use an Integer variable as the iterator - it only lets you use Pair or DictionaryEntry. That’s why I suspect an inheritance relationship between those two classes.
Actually, it was a simple mistake on my part that got me here; I forgot that Dictionaries don’t iterate using Pairs.