为什么标记装配ComVisible(true)气馁?

Tra*_*kel 20 .net com

我总是将我的.NET程序集标记为COM可见[assembly: ComVisible(true)],以为我从来不知道有人可能需要从COM调用它们.我也开始使用FxCop并开始从代码分析中看到这个警告:

CA1017:Microsoft.Design:因为"MyLibrary.dll"公开了外部可见类型,所以在程序集级别使用ComVisible(false)标记它,然后使用ComVisible标记应该向COM客户端公开的程序集中的所有类型(true)

是否有一些理由让您不希望所有公共类型都暴露给COM?我猜这有,但我无法想象这是什么原因.如果有的话,它似乎非常不方便.

Tim*_*oyd 27

关键是导出COM接口不是免费的,因为必须满足不兼容性和要求.必须考虑并保持这一点.(警告CA1017暗指这一点.)

因此,我一直使用"选择加入"的理念而不是"选择退出",即不是让所有COM都可见,我将程序集标记为COM不可见.然后我专注于有选择地暴露类型\成员(即通过选择),并确保暴露的API对于COM是理智的(例如COM不支持泛型,方法重载或带参数的构造函数)以及它具有已经考虑过COM的测试.通过这种方式,将API暴露给COM是以严格,经过测试,限制和可维护的方式完成的.

这与使所有COM可见并且随后担心任何潜在问题相反,请记住,如果您已经暴露了所有内容,那么可能存在与您不期望的COM接口用户的耦合,现在将难以退出的.

从记忆中可以看出一些意想不到的后果:

  1. 导出重载方法时,默认情况下会导出它们并使用序列号命名,例如OverloadedMethod1,OverloadedMethod2等.如果您重构代码并更改方法的顺序或插入重载等,那么您就会遇到任何问题.已经使用过以前的COM接口中的这​​些方法.OverloadedMethod1和OverloadedMethod2可能已被交换.

  2. 暴露给COM的类必须具有无参数构造函数.如果没有维护此合同的单元测试,那么很容易在以后更改该类,以便它没有无参数构造函数,从而破坏了COM接口用户.


The*_*ide 6

作为参考,如果未应用程序集级别ComVisibleAttribute,则假定所有公共类都是COM Visible.未能标记程序集[assembly: ComVisible(false)]通常会导致以下代码分析警告,即使对于未标记的类型[ComVisible(true)]:

CA1405:COM可见类型基类型应该是COM可见的


Tob*_*oby 5

随着泛型和其他高级类型的出现,现在更常见的方法是公开不能 COM可见的类型,而不是公开可以公开的类型.

CA1017中推荐的方法旨在鼓励您公开那些您打算向COM 公开的类型.