2010-07-22 119 views
16

我一直标记着我的.NET程序集对于COM来说是可见的,我认为我不知道什么时候有人可能需要从COM调用它们。我也开始使用的FxCop并开始看到从代码分析这样的警告:为什么要标记组件ComVisible(true)不鼓励?

CA1017:Microsoft.Design:因为“MyLibrary.dll”公开外部可见的类型,在组件级别与标记有ComVisible特性(假)标记,然后纪念集会中的所有类型应该暴露在COM客户标记有ComVisible特性(真)

是有一些原因,你为什么会不只是要所有暴露给COM的公共类型的?我猜测有,但我无法想象这是什么原因。如果有的话,似乎显得很不方便。

回答

22

我还没有与COM互操作很长一段时间,但在过去,我一直与“选入”的理念,而不是“退出”,而不是使一切COM可见,我标志着组装为不可见COM。然后我专注于选择性暴露类型\成员(即通过选择),并确保所暴露的API对COM来说是健全的(例如,COM不支持Genrics,方法重载或带参数的构造函数),并且它具有考虑到了COM的测试。以这种方式将API暴露给COM是以严格的,经过测试的,有界的和可维护的方式完成的。

这与使所有COM可见并在之后担心任何潜在问题相反,要记住如果您已经暴露了一切,那么可能会与COM接口的用户发生联系,这是您不期望的现在难以退出。

从存储器中的几个的意想不到的后果的例子:

  1. 当导出重载方法,它们与序列号导出并默认名为例如OverloadedMethod1,OverloadedMethod2等等。如果你重构你的代码,改变你的方法的顺序或者插入一个重载等,那么你就会遇到任何使用你以前的COM接口使用这些方法的人的麻烦。 OverloadedMethod1和OverloadedMethod2可能已被交换。

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

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

5

使用泛型和其他高级类型的出现,这是比较常见的现在的方法来揭露类型不能是COM可见绝对比他们揭露类型可以

在CA1017推荐的方法是为了鼓励你揭露那些你打算暴露于COM类型。

4

仅供参考,如果未应用汇编级别ComVisibleAttribute,则所有公共类都被假定为COM可见。未按规定标注的组件,[assembly: ComVisible(false)]往往会导致下面的代码分析警告,即使没有标记[ComVisible(true)]类型:

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

1

这是很简单的给在MSDN.这是怎样的方式来解决此警告:

using System; 
using System.Runtime.InteropServices; 

[assembly: ComVisible(false)] 
namespace InteroperabilityLibrary 
{ 
    [ComVisible(false)] 
    public class BaseClass 
    { 
     public void SomeMethod(int valueOne) {} 
    } 

    // This class violates the rule. 
    [ComVisible(true)] 
    public class DerivedClass : BaseClass 
    { 
     public void AnotherMethod(int valueOne, int valueTwo) {} 
    } 
} 

如果基类中,你在你的代码中引用任何DLL。然后,为派生类制作[COMVisibible(True)]。它适用于我的场景。

+0

问题不在于如何解决。问题是这个警告首先试图警告的是什么。 – sharptooth 2015-04-29 08:07:00

+0

AS MSDN还定义了此警告的根本原因,即“组件对象模型(COM)可见类型派生自不可见COM的类型。” – 2015-04-29 08:36:55

+1

即使没有警告,这也不是一个难以发现的问题。一个非常粗糙和微妙的部分是,你将拥有一个ComVisible程序集在COM中注册的所有公共内容。 – sharptooth 2015-04-29 08:42:04

相关问题