Каковы альтернативы коллективным коллекциям для COM Interop?

Я пытаюсь вернуть коллекцию отделов из сборки .NET, которая будет использоваться ASP через COM Interop. Используя .NET, я просто вернул бы общую коллекцию, например. List<Department>, но, похоже, дженерики не работают с COM Interop. Итак, каковы мои варианты?

Я хотел бы как перебрать список, так и получить доступ к элементу по индексу. Должен ли я наследовать от List<Department>, реализовать IList, IList<Department> или другой интерфейс, или есть лучший способ? В идеале я бы предпочел не создавать индивидуальную коллекцию для каждого типа списка, который мне нужен. Кроме того, будет List[index] работать с COM Interop?

Спасибо, Mike

Пример .NET-компонентов (С#):

public class Department {
    public string Code { get; private set; }
    public string Name { get; private set; }
    // ...
}

public class MyLibrary {
    public List<Department> GetDepartments() {
        // return a list of Departments from the database
    }
}

Пример кода ASP:

<%
Function PrintDepartments(departments)
    Dim department
    For Each department In departments
        Response.Write(department.Code & ": " & department.Name & "<br />")
    Next
End Function

Dim myLibrary, departments
Set myLibrary = Server.CreateObject("MyAssembly.MyLibrary")
Set departments = myLibrary.GetDepartments()
%>
<h1>Departments</h1>
<% Call PrintDepartments(departments) %>
<h1>The third department</h1>
<%= departments(2).Name %>

Похожие вопросы:

Ответ 1

После нескольких исследований и проб и ошибок, я думаю, что нашел решение, используя System.Collections.ArrayList. Однако это не работает с получением значения по индексу. Для этого я создал новый класс ComArrayList, который наследует от ArrayList и добавляет новые методы GetByIndex и SetByIndex.

Совместимость с COM Interop:

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;
    }
}

Обновлен компонент .NET MyLibrary.GetDepartments:

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

Обновлен ASP:

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

Ответ 2

Поскольку вы потребляете только данные в ASP, я бы предложил вернуться Department[]. Это должно отображаться непосредственно в SAFEARRAY в COM. Он также поддерживает перечисление и индексированный доступ.

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

Ответ 3

В вашем ASP-коде вы не могли этого сделать?

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

Я знаю, что в VB.NET индексы С# поддерживаются с помощью свойства "Item", поэтому одна и та же идея может работать в ASP.

Ответ 4

Я пытаюсь решить эту же проблему в vb.net(не владея С#).

Так как List (Of T) поддерживает интерфейс IList, для COM-интерфейса для моих объектов я попытался указать

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

а затем указав в открытом интерфейсе, что COM видит

ReadOnly Property MyList As IList

Это, похоже, отлично работает с классическим ASP-клиентом, который создает экземпляр объекта, вызывает функцию генератора, а затем считывает свойство MyList как массив.