Quelles sont les alternatives aux collections génériques pour COM Interop?
-
06-07-2019 - |
Question
J'essaie de renvoyer un ensemble de départements d'un assemblage .NET à utiliser par ASP via COM Interop. Avec .NET, je voudrais simplement renvoyer une collection générique, par exemple. List<Department>
, mais il semble que les génériques ne fonctionnent pas bien avec COM Interop. Alors, quelles sont mes options?
Je voudrais à la fois parcourir la liste et pouvoir accéder à un élément par index. Devrais-je hériter de IList
, implémenter une IList<Department>
, List[index]
ou une autre interface, ou existe-t-il un meilleur moyen? Idéalement, je préférerais ne pas avoir à implémenter une collection personnalisée pour chaque type de liste dont j'ai besoin. De même, <=> fonctionnera-t-il même avec COM Interop?
Merci, Mike
Exemple de composants .NET (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
}
}
Exemple de code 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 %>
Questions connexes:
La solution
Après quelques recherches et essais, je pense avoir trouvé une solution en utilisant System.Collections.ArrayList
. Cependant, cela ne fonctionne pas avec l'obtention d'une valeur par index. Pour ce faire, j'ai créé une nouvelle classe ComArrayList
qui hérite de ArrayList
et ajoute de nouvelles méthodes GetByIndex
et SetByIndex
.
Collection compatible 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;
}
}
Mise à jour du composant .NET MyLibrary.GetDepartments:
public ComArrayList GetDepartments() {
// return a list of Departments from the database
}
ASP mis à jour:
<h1>The third department</h1>
<%= departments.GetByIndex(2).Name %>
Autres conseils
Étant donné que vous ne consommez que les données en ASP, je vous conseillerais de renvoyer Department[]
. Cela devrait correspondre directement à un SAFEARRAY dans COM. Il prend également en charge l’énumération et l’accès indexé.
public Department[] GetDepartments() {
var departments = new List<Department>();
// populate list from database
return departments.ToArray();
}
Dans votre code ASP, ne pourriez-vous pas le faire?
<h1>The third department</h1>
<%= departments.Item(2).Name %>
Je sais que dans VB .NET, les indexeurs C # sont pris en charge via le " Item " propriété, donc la même idée peut fonctionner en ASP.
J'ai essayé de résoudre le même problème dans vb.net (ne parle pas couramment le C #).
Puisque List (Of T) prend en charge l'interface IList, j'ai essayé de spécifier l'interface COM pour mes objets
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
puis en spécifiant dans l'interface publique que COM voit
ReadOnly Property MyList As IList
Cela semble fonctionner correctement à partir d'un client ASP classique qui instancie l'objet, appelle une fonction de générateur, puis lit la propriété MyList comme un tableau.