Generics được thêm vào .NET 2.0 và COM tồn tại trước .NET 1.0.
(Và là công nghệ .NET nhằm để thay thế.)
COM không bao giờ có Generics, và do đó bạn không thể tiếp xúc với họ.
Không có ngôn ngữ COM nào (C++, VB6, Delphi) đều có generics để bạn không thể mong đợi chúng được tiêu thụ.
(Vâng, C++ đã có mẫu nhưng họ hoàn toàn một con thú khác nhau, và COM chỉ có nghĩa là giao diện.)
Phơi bày các bộ sưu tập như một ArrayList
là solution cho vấn đề này, bạn không thể làm việc xung quanh nó.
Tuyên bố từ chối: Tôi không có chuyên gia về COM nên phần còn lại của câu trả lời là dựa trên dự đoán của tôi.
COM không bao giờ “đã” ArrayList
s, đúng, nhưng vì thế nó không bao giờ có bất kỳ của các lớp trong .NET Framework, bởi vì nó không phải là một khuôn khổ riêng của mình. Tuy nhiên, một số loại .NET có được trong các thư viện kiểu được xuất, và một số thì không. Còn các lớp .NET Framework thì sao? Vâng, ArrayList
là [ComVisible]
và List<T>
thì không.
Tại sao?
COM works via interfaces và Ngôn ngữ định nghĩa giao diện không có đầu mối về generics và không hỗ trợ chúng. Các ngôn ngữ hỗ trợ COM, chẳng hạn như VB6 hoặc C++, sẽ không biết phải làm gì với các generics.
Nếu có cách tạo giao diện cho List<T>
, nó sẽ không chứa T
trong đó để về cơ bản không có điểm cố gắng vạch trần loại chung. Các lựa chọn thay thế tưởng tượng có thể có cho điều này sẽ là:
- Tạo phiên bản giao diện "cụ thể" cho loại chung, ví dụ:
IListOfString
cho List<string>
- Xóa thông tin loại chung chung (giống như Java không biên dịch) và thay thế
T
bằng object
.
Tùy chọn đầu tiên là không khả thi vì bê tông T
loại có thể không được biết đến ở biên soạn (đọc: Reflection), và List<T>
không có một thuộc tính [ComVisible]
vào nó anyway.
Lựa chọn thứ hai là thực sự loại càng tốt vì bạn có thể provide your own class interface with IList
and ICollection
properties:
[ComVisible(true)]
public interface IPerson
{
string Name { get;set;}
DateTime Entered { get;set;}
IList NickNamesList { get;}
ICollection NickNamesCollection { get;}
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComDefaultInterface(typeof(IPerson))]
public class Person:IPerson
{
[ComVisible(false)]
public List<string> NickNames
{
get { return _NickNames; }
set { _NickNames = value; }
}
private List<string> _NickNames = new List<string>();
#region IPerson Members
IList IPerson.NickNamesList
{
get { return this.NickNames; }
}
ICollection IPerson.NickNamesCollection
{
get { return this.NickNames; }
}
#endregion
....
}
Đây là một cách giải quyết và không trả lời câu hỏi của bạn mặc dù.
Tôi thực sự tự hỏi liệu bạn có thể lấy được lớp học StringList
từ List<string>
và đánh dấu nó là [ComVisible(true)]
. Bạn có thể muốn kiểm tra điều đó.
Vì COM không hỗ trợ Generics. Hãy xem [this] (http://stackoverflow.com/questions/1862497/c-exposing-class-to-com-generic-collections) và [this] (http://stackoverflow.com/questions/ Câu hỏi 269581/giải pháp thay thế-cho-chung-bộ sưu tập-cho-com-interop). –