Каковы альтернативы коллективным коллекциям для 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 как массив.