What are alternatives to generic collections for COM Interop?

Solution 1:

After some more research and trial-and-error, I think I found a solution by using System.Collections.ArrayList. However, this does not work with getting a value by index. To do so, I created a new class ComArrayList that inherits from ArrayList and adds new methods GetByIndex and SetByIndex.

COM Interop compatible collection:

public class ComArrayList : System.Collections.ArrayList {
    public virtual object GetByIndex(int index) {
        return base[index];
    }

    public virtual void SetByIndex(int index, object value) {
        base[index] = value;
    }
}

Updated .NET component MyLibrary.GetDepartments:

public ComArrayList GetDepartments() {
    // return a list of Departments from the database
}

Updated ASP:

<h1>The third department</h1>
<%= departments.GetByIndex(2).Name %>

Solution 2:

Since you are only consuming the data in ASP, I would suggest returning Department[]. This should map directly to a SAFEARRAY in COM. It supports enumeration and indexed access too.

public Department[] GetDepartments() {
    var departments = new List<Department>();
    // populate list from database
    return departments.ToArray();
}

Solution 3:

In your ASP code, could you not do this?

<h1>The third department</h1>
<%= departments.Item(2).Name %>

I know that in VB .NET, C# indexers are supported via the "Item" property, so the same idea may work in ASP.

Solution 4:

I've been trying to address this same problem in vb.net (not fluent in C#).

Since List(Of T) supports the IList interface, for the COM interface for my objects I have tried specifying

Public Class MyClass
...
   Private _MyList As List(of MyObject)
   Public ReadOnly Property MyList As IList Implements IMyClass.MyList
    Get
        Return _MyList
    End Get
   End Property

and then specifying in the Public Interface that COM sees

ReadOnly Property MyList As IList

This seems to work fine from a classic ASP client that instantiates the object, calls a generator function and then reads MyList property like an array.