Каковы альтернативы универсальным коллекциям для COM-взаимодействия?

StackOverflow https://stackoverflow.com/questions/269581

Вопрос

Я пытаюсь вернуть коллекцию отделов из сборки .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 как массив.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top