c# - 如何将 "generic"C# 集合公开给 COM

标签 c# com vb6 com-interop

我有一个 API,我为此开发了一个 C# 客户端,可将 HTTP GET 请求转换为 C# 对象。

我已经在 VB6 中使客户端 COM 可见,因为我需要它,这里的问题是通用集合不能在 COM 上工作。我已经通过自己实现一个集合来解决这个问题,但它不是通用的。

这意味着我的每个类都有一个名为 [Class]_Collection 的类,这只是意味着我有一个没有通用类的集合。

这很好用,除了我们的 API 非常大,有很多不同的对象,所以如果我不必为我们的 API 中的每个类都编写实现,那就太好了。

我一直在尝试可以继承的通用基类或通用接口(interface),但如前所述,COM 不喜欢通用类。 我还需要一个 IDispatch 接口(interface)来公开功能,以便在 VB6 中公开类函数。

有没有一种方法可以让我为我的所有集合编写实现,并在需要的地方继承该功能?

最佳答案

泛型确实与 COM 不兼容,据我所知,没有办法绕过该限制。

我用作简单解决方法的方法是添加专门用于 COM 互操作目的的包装器属性。

例子:

[ComVisible(false)]
public List<int> SomeNumbers {get; set;}

[ComVisible(true)]
[Obsolete("Use this for COM interop only")]
public IList SomeNumbersCOM => SomeNumbers;

这样做的好处是相当简单,实际上不复制任何数据,并且通过 COM 运行。然而,它显然不是类型安全的,因为在 VB6 中,SomeNumbersCOM 的条目将只是显示为 object。但是 VB6 无论如何都不是特别安全的,所以这可能不是什么大问题。至少真正的强类型集合可以在 C# 中使用。 Obsolete 有助于强制执行此操作。

根据我的经验,类型安全性的轻微损失并不是真正的问题。您仍然可以在 VB 端断言正确的类型;例如,从 SomeNumbersCOM 列表中获取值时使用 Long 变量。

您不必添加太多不只是样板的代码。例如,您不必实际编写集合类代码或复制它们的内部逻辑。


您可以创建一个完整的包装器类,而不是将属性包装在同一个类中,这对于 C# 使用者来说会更简洁一些。

创建一个完全独立的 COM 可见性包装器程序集(其中包含所有这些包装器类)将是强制不从 C# 端的其他地方使用包装器的更强大的方法。

关于c# - 如何将 "generic"C# 集合公开给 COM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72013699/

相关文章:

c# - Youtube登录使用c#

c# - 为什么我的应用程序在注销/关闭时没有关闭(c#/.net winforms)?

vb.net - 运算符 '-' 未定义 VB6 到 VB.NET

excel - 在 VBA 中转到 <行号>

c# - 在 c# 中使用 mysql 时计算受影响的行数

C# Linq Where 和 Regex

c# - 有没有办法确定表单的文本是否适合?

python win32 com 关闭itunes

c++ - 如何在 COM 接口(interface)定义中指定用户定义的类型参数?

vb6 - 是否有必要在将 Adodb.recordset 对象设置为空之前关闭它?