Каковы альтернативы универсальным коллекциям для COM-взаимодействия?
-
06-07-2019 - |
Вопрос
Я пытаюсь вернуть коллекцию отделов из сборки .NET для использования ASP через COM-взаимодействие.Используя .NET Я бы просто вернул общую коллекцию, например List<Department>
, но, похоже, что дженерики плохо работают с COM-взаимодействием.Итак, какие у меня есть варианты?
Я хотел бы как выполнить итерацию по списку, так и иметь возможность получить доступ к элементу по индексу.Должен ли я наследовать от List<Department>
, внедрить IList
, IList<Department>
или другой интерфейс, или есть способ получше?В идеале я бы предпочел не внедрять пользовательскую коллекцию для каждого типа списка, который мне нужен.Кроме того, будет List[index]
даже работать с COM-взаимодействием?
Спасибо, Майк
Пример .СЕТЕВЫЕ компоненты (C #):
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 %>
Сопутствующие вопросы:
Решение
После еще некоторых исследований и проб и ошибок, я думаю, что нашел решение, используя System.Collections.ArrayList
.Однако это не работает с получением значения по индексу.Для этого я создал новый класс ComArrayList
который наследуется от ArrayList
и добавляет новые методы GetByIndex
и SetByIndex
.
Коллекция, совместимая с COM-взаимодействием:
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;
}
}
Обновлено .MyLibrary СЕТЕВОГО компонента.GetDepartments:
public ComArrayList GetDepartments() {
// return a list of Departments from the database
}
Обновленный ASP:
<h1>The third department</h1>
<%= departments.GetByIndex(2).Name %>
Другие советы
Поскольку вы используете данные только в ASP, я бы предложил вернуть Department[]
.Это должно быть сопоставлено непосредственно с SAFEARRAY в COM.Он также поддерживает перечисление и индексированный доступ.
public Department[] GetDepartments() {
var departments = new List<Department>();
// populate list from database
return departments.ToArray();
}
В вашем ASP-коде вы не могли бы этого не делать?
<h1>The third department</h1>
<%= departments.Item(2).Name %>
Я знаю, что в VB .NET индексаторы C # поддерживаются через свойство "Item", поэтому та же идея может сработать и в ASP.
Я пытался решить эту же проблему в vb.net (не свободно владеет C #).
Поскольку 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 как массив.