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.