gpt4 book ai didi

generics - 为什么 ArrayList 可以与 COM 互操作一起使用,而 IList 不能?

转载 作者:行者123 更新时间:2023-12-04 11:59:02 25 4
gpt4 key购买 nike

我注意到,如果我制作了一个公开 ArrayList 的 .NET 组件,那么 ArrayList 会通过 COM Interop 并以脚本语言(例如 VBScript)提供。

泛型,例如 IList<T>似乎不起作用。

为什么会这样,有什么方法可以使泛型类型成功地通过 COM Interop 流向脚本引擎?

最佳答案

.NET 2.0 中添加了泛型,COM 存在于 .NET 1.0 之前。
(并且是 .NET 旨在取代的技术。)

COM 从来没有泛型,因此您不能公开它们。
COM 语言(C++、VB6、Delphi)都没有泛型,所以你不能指望它们会被使用。
(嗯,C++ 有模板,但它们是完全不同的野兽,COM 只意味着接口(interface)。)

将集合公开为 ArrayListsolution对于这个问题,你无法解决它。

Disclaimer: I am no expert on COM so the rest of the answer is roughly based on my guesses.



COM 从未“拥有” ArrayList s,是的,但是它在 .NET Framework 中从来没有任何类,因为它本身不是一个框架。但是,有些 .NET 类型会进入导出的类型库,而有些则不会。 .NET Framework 类呢?好吧, ArrayList[ComVisible] , 和 List<T>不是。

为什么?

通讯 works via interfaces ,并且接口(interface)定义语言对泛型一无所知,也不支持它们。支持 COM 的语言,例如 VB6 或 C++,不知道如何处理泛型。

如果有办法为 List<T> 生成接口(interface), 它不会包含 T在其中,因此尝试公开泛型类型基本上没有意义。可能的想象替代方案是:
  • 为泛型类型生成“特定”版本的接口(interface),例如IListOfString对于 List<string>
  • 删除泛型类型信息(很像 Java 在编译时所做的)并替换 Tobject .

  • 第一个选项不可行,因为具体 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> 的类(class)并将其标记为 [ComVisible(true)] .你可能想检查一下。

    关于generics - 为什么 ArrayList 可以与 COM 互操作一起使用,而 IList<T> 不能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7003844/

    25 4 0