Generics 为什么ArrayList与COM互操作一起工作,而IList<;T>;不';T

Generics 为什么ArrayList与COM互操作一起工作,而IList<;T>;不';T,generics,scripting,com-interop,Generics,Scripting,Com Interop,我注意到,如果我制作了一个公开ArrayList的.NET组件,那么ArrayList将通过COM互操作,并且可以在脚本语言(如VBScript)中使用 诸如IList之类的泛型似乎不起作用 这是为什么?有没有办法使泛型类型成功地通过COM互操作流到脚本引擎?泛型是在.NET 2.0中添加的,COM在.NET 1.0之前就存在了。 (这项技术.NET的目标是要取代它。) COM从来没有泛型,因此您无法公开它们。 两种COM语言(C++、VB6、Delphi)都没有泛型,因此您不能期望它们被使用。

我注意到,如果我制作了一个公开ArrayList的.NET组件,那么ArrayList将通过COM互操作,并且可以在脚本语言(如VBScript)中使用

诸如
IList
之类的泛型似乎不起作用


这是为什么?有没有办法使泛型类型成功地通过COM互操作流到脚本引擎?

泛型是在.NET 2.0中添加的,COM在.NET 1.0之前就存在了。
(这项技术.NET的目标是要取代它。)

COM从来没有泛型,因此您无法公开它们。
两种COM语言(C++、VB6、Delphi)都没有泛型,因此您不能期望它们被使用。
(嗯,C++有模板,但它们完全是不同的动物,而COM只意味着接口。)< /P> 将集合公开为
ArrayList
是解决此问题的关键,您无法解决此问题

免责声明:我不是COM方面的专家,因此其余答案大致基于我的猜测

COM从来没有“拥有”
ArrayList
s,这是真的,但它从来没有.NETFramework中的任何类,因为它本身不是一个框架。但是,有些.NET类型会进入导出的类型库,有些则不会。那么.NETFramework类呢?嗯,
ArrayList
[ComVisible]
,而
List
不是

为什么?

COM,接口定义语言没有关于泛型的线索,也不支持泛型。支持COM的语言,如VB6或C++,不知道如何处理泛型。 如果有一种方法可以为
List
生成接口,那么它将不包含
T
,因此基本上没有必要公开泛型类型。可能的替代方案是:

  • 为泛型类型生成接口的“特定”版本,例如
    listofstring
    for
    List
  • 擦除泛型类型信息(与Java在编译时所做的非常类似),并将
    T
    替换为
    object
第一个选项不可行,因为编译时可能不知道具体的
T
类型(读取:反射),而且
List
上也没有
[ComVisible]
属性

第二个选项实际上是可能的,因为您可以:

[ComVisible(true)]
公共接口IPerson
{
字符串名称{get;set;}
输入的日期时间{get;set;}
IList昵称列表{get;}
ICollection昵称集合{get;}
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComDefaultInterface(typeof(IPerson))]
公共类人士:IPerson
{
[ComVisible(false)]
公共列表昵称
{
获取{return\u昵称;}
设置{u昵称=值;}
}
私有列表_昵称=新列表();
#区域IPerson成员
IList IPerson.昵称列表
{
获取{返回this.昵称;}
}
i收集IPerson.昵称收集
{
获取{返回this.昵称;}
}
#端区
....
}
这是一个变通方法,但不能回答您的问题


我实际上想知道您是否可以从
List
派生
StringList
类,并将其标记为
[ComVisible(true)]
。您可能需要对此进行检查。

因为COM不支持泛型。看看这个问题,我不能接受。微软让ArrayList起作用(COM从来没有ArrayList)——所以一定有可能以某种方式让其他类型起作用。泛型在运行时具有具体类型。什么是使ArrayList工作的机制?我不是COM方面的专家,但我编辑了答案以纳入我的一些猜测。让我们假设后期绑定(IDispatch),看看这是否会给事情带来不同的倾向。每个.NET类型在运行时都是具体类型,因此只要从COM组件使用后期绑定,它就应该能够“看到”从泛型派生的具体类型。由于COM有自己的类型系统,因此需要在.NET类型和COM类型之间进行一些转换。今天我读了一些书,现在我想知道是否可以使用自定义封送拆收器将泛型类型“公开”到COM?不过我对COM的了解还很薄弱,所以我只是在瞎猜。
[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
    ....
}