37

MSDN has this article about [ComVisible] attribute. I don't quite get what happens when one sets [ComVisible(true)].

MSDN says

The default is true, which indicates that the managed type is visible to COM. This attribute is not needed to make public managed assemblies and types visible; they are visible to COM by default. Only public types can be made visible.

So they say public types are visible to COM by default. But they also say only public types can be made visible by setting [ComVisible(true)]. It does not makes sense: if public types are visible by default, then how does setting [ComVisible(true)] make public types visible? If they're already visible how will they get more visible?

Perhaps my understanding is not correct. I shall appreciate if anyone can put some light on the above statements.

sharptooth
  • 167,383
  • 100
  • 513
  • 979
user2166888
  • 579
  • 1
  • 5
  • 13
  • 7
    One confusing aspect is that the default Visual Studio Class Library template adds an [assembly:ComVisible(false)] attribute (in AssemblyInfo.cs). This sets the 'default' for all types in the project to false. The 'Make assembly COM-Visible' flag in the Assembly Information on the project properties sets this. – Govert Mar 31 '13 at 14:36
  • 2
    There is a trick here. The default value of ComVisible is true alright, if it is not set by anyone, but Visual Studio sets this value to false. Which means your assembly won't be ComVisible unless you turn it on manually. But before VS2008 this attribute was indeed set to true by default. – Johnny Feb 13 '14 at 06:14

2 Answers2

29

The trick is you can also add this attribute at assembly level (in AssemblyInfo.cs). If you specify [assembly: ComVisible(true)] (or don't specify that at assembly level and so have the same effect by default) then all the public classes and interfaces and public methods thereof become COM-visible by default.

You could just as well set [assembly: ComVisible(false)] at assembly level and then all the public entities would by default have the same effect as if they had [ComVisible(false)] on them and so you could only mark those classes/interfaces/methods COM-visible ([ComVisible(true)]) which you really need.

This helps you to not expose too much when you have lots of public entities as here. Without this mechanism you would have to set [ComVisible(false)] to each class/interface/method that you don't want exposed. Using [assembly: ComVisible(false)] lets you only expose the stuff you need.

And you only can expose public entities to COM (be default or explicitly) - entities with stricter visibility can't be exposed to COM.

Community
  • 1
  • 1
sharptooth
  • 167,383
  • 100
  • 513
  • 979
22

It does not makes sense, when public types are visible by default, so how does setting ComVisible attribute to true [ComVisible(true)] makes public types visible.

They're visible by default because the default value of the ComVisibleAttribute is true. Setting the attribute explicitly to true doesn't change anything, it just makes your intentions more clear. That's the very first line of the documentation you found:

The default is true, which indicates that the managed type is visible to COM. This attribute is not needed to make public managed assemblies and types visible; they are visible to COM by default. Only public types can be made visible. The attribute cannot be used to make an otherwise internal or protected type visible to COM or to make members of a nonvisible type visible.

Basically, you can think of it like the compiler always adds [ComVisibleAttribute(true)] to your code by default if you don't do it yourself.

The only reason you would need to set this attribute is to prevent public types from being COM-visible (in which case you would set it to false). The default already ensures their visibility.

Obviously, non-public types (e.g., private and protected) cannot and will not ever be visible to COM. This attribute has no effect on types with such accessibility.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
  • 4
    they are not exactly the same. If the ComVisible will be set to false on the assembly level for example, the "true" set somewhere inside a class will override it – Joezer May 29 '16 at 06:03