我注意到如果我创建一个公开ArrayList的.NET组件,那么该ArrayList将通过COM Interop并以脚本语言(如VBScript)提供。
泛型,例如IList<T>
似乎不起作用。
为什么这样,是否有任何方法可以使通用类型成功地通过COM Interop流向脚本引擎?
答案 0 :(得分:6)
.NET 2.0中添加了泛型,.NET 1.0之前存在COM (并且.NET 旨在替换的技术。)
COM从来没有使用泛型,因此你不能暴露它们 COM语言(C ++,VB6,Delphi)都没有泛型,所以你不能指望它们被消费。将集合公开为ArrayList
是此问题的solution,您无法解决此问题。
免责声明:我不是COM的专家,所以答案的其余部分大致基于我的猜测。
COM永远不会“拥有”ArrayList
s,但是因此它从未在.NET Framework中拥有任何类,因为它本身不是框架。但是,某些.NET类型会进入导出的类型库,而有些则不会。那么.NET Framework类呢?好吧,ArrayList
是[ComVisible]
,List<T>
不是。
为什么?
COM works via interfaces,接口定义语言没有关于泛型的线索,也不支持它们。支持COM的语言(如VB6或C ++)不知道如何处理泛型。
如果有一种方法可以为List<T>
生成一个接口,那么不中包含T
,因此尝试公开泛型类型基本没有意义。可能的想象替代方案是:
IListOfString
List<string>
T
替换为object
。第一个选项不可行,因为在编译时可能不知道具体的T
类型(读取:反射),并且List<T>
无论如何都没有[ComVisible]
属性
第二种选择实际上是可行的,因为你可以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
....
}
这是一种解决方法,但不会回答您的问题。
我实际上想知道您是否可以从StringList
派生List<string>
课程并将其标记为[ComVisible(true)]
。你可能想检查一下。