Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making sense of IEnumerable in .Net COM Interop

Why can I use the VBScript for each statement to iterate a System.Collections.ArrayList oject, but not a Systems.Collections.SortedList object?

Given the following:

set aList = Server.CreateObject("System.Collections.ArrayList")
aList.Add "a"
aList.Add "b"
aList.Add "c"
for each item in aList
    ' do something
next

set sList = Server.CreateObject("System.Collections.SortedList")
sList.Add "a", 1
sList.Add "b", 2
sList.Add "c", 3
for each item in sList
    ' do something
next

The line

for each item in sList

crashes with

object doesn't support this property or method*.

By this property I assume they mean the _NewEnum property. But why is _NewEnum being exposed by ArrayList, but not SortedList? Both classes implement the IEnumberable interface which from disassembling mscorelib.dll appears to be the interface responsible for implementing the _NewEnum property (dispId of -4).

If anyone can shed some light on the different COM interop behavior of these similar classes I'd be very appreciative.

I know I can use other properties exposed by SortedList to iterate over the collection. I'm not asking how to iterate a SortedList. I'm just asking why IEnumrable doesn't seem to be implemented in the interop version of SortedList when it is implemented in the interop version of ArrayList.

like image 936
smarcaurele Avatar asked Feb 28 '12 17:02

smarcaurele


1 Answers

Although SortedList does implement IEnumerable it has an overloaded GetEnumerator() method which returns IDictionaryEnumerator. You have to cast explicitly to IEnumerable to use the overload that returns IEnumerator which may be where your problem lies.

The default enumerator does not have the same behaviour as that of ArrayList - it will return a DictionaryEntry for each item rather than the strings you might be expecting.

My guess would be you probably want to use the Values property instead and that, if you're sorting by the numbers, you want to use the Add method arguments the other way around i.e.

sList.Add 1, "a"
like image 85
dezfowler Avatar answered Nov 15 '22 11:11

dezfowler