泛型是在 .NET 2.0 中添加的,COM 在 .NET 1.0 之前就已经存在。
(.NET 技术aimed取代。)
COM 从来没有泛型,因此您不能公开它们。
两种 COM 语言(C++、VB6、Delphi)都没有泛型,因此您不能指望它们会被使用。
(嗯,C++ 有模板,但它们是完全不同的野兽,而 COM 仅意味着接口.)
将集合公开为ArrayList
is the solution https://stackoverflow.com/questions/269581/what-are-alternatives-to-generic-collections-for-com-interop对于这个问题,你无法解决它。
免责声明:我不是 COM 方面的专家,所以其余的答案大致基于我的猜测。
COM 从未“拥有”ArrayList
s,确实如此,但它从未有过any.NET Framework 中的类,因为它本身不是框架。但是,某些 .NET 类型会进入导出的类型库,而有些则不会。 .NET Framework 类怎么样?出色地,ArrayList
is [ComVisible]
, and List<T>
不是。
Why?
COM 通过接口工作 http://en.wikipedia.org/wiki/Component_Object_Model#Interfaces,并且接口定义语言对泛型一无所知,也不支持它们。支持 COM 的语言(例如 VB6 或 C++)不知道如何处理泛型。
如果有一种方法可以生成一个接口List<T>
, 它会not包含T
因此尝试公开泛型类型基本上没有意义。可能的想象替代方案是:
- 为通用类型生成“特定”版本的接口,例如
IListOfString
for List<string>
- 删除泛型类型信息(很像 Java 在编译时所做的那样)并替换
T
with object
.
第一种选择不可行,因为具体T
编译时可能不知道类型(阅读:反射),并且List<T>
没有[ComVisible]
无论如何属性。
第二种选择实际上是可能的,因为你可以提供您自己的类接口IList and ICollection特性 http://www.west-wind.com/weblog/posts/2007/Jul/10/Generics-and-COM-Interop-dont-mix#192110:
[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
....
}
这是一种解决方法,但不能回答您的问题。
我实际上想知道你是否可以得出你的StringList
班级来自List<string>
并将其标记为[ComVisible(true)]
。您可能想检查一下。