Understand C # COM Interfaces

The Microsoft.Office.Interop.Word._Document interface has a method with the following signature:

void Close(ref object SaveChanges = Type.Missing, ref object OriginalFormat = Type.Missing, ref object RouteDocument = Type.Missing); 

A few points that I encounter:

  • The ref parameter cannot have a default value.
  • The default value should be constant, but Type.Missing not.
  • When calling this method, I can use Close(false) - usually ref parameter requires an assignable variable?
  • When I go to the Type definition in Visual Studio, it returns me to the _Document.Type property, but this property does not have a property called Missing . Is this a bug in VS?

Thanks for any explanation.

+6
source share
2 answers

This is a quirk introduced in C # version 4. It is not exclusive to COM COM code, you can also get it in your own code. Try the following:

 using System; using System.Runtime.InteropServices; class Program { static void Example([Optional] object arg) { } static void Main(string[] args) { Example( // <== Look at the IntelliSense popup here } } 

This [Optional] attribute triggers this behavior. It was forever, but it was never especially useful in C # before. Unlike other languages ​​such as VB.NET and C ++ / CLI. Starting with C # v4, it interprets the attribute in different ways, and the compiler will hard code Type.Missing as an optional value for the type of the object argument. Try changing the type of the argument to, say, a string, and note that the default value becomes different. Zero, as you would expect.

This is not very good, of course, Type.Missing is a rather strange default value for an object in regular C # code. Everyone would expect zero. However, it’s very practical that writing Office interaction code in C # in versions prior to 4 was pretty awful. Companies can run into problems when they do things like this, by the way, if Neilie Cruz gets it, she will make Microsoft pay a billion euros for it :)

+3
source

The fact is that the InterOp library is not actually written in C # and should not comply with C # rules. The only thing that should be is IL.

Visual Studio Metadata Viewer is struggling to show you metadata in your chosen language (in this case, C #), because it is usually much more readable than using IL code.

In some cases, this can be misleading (for example, ref parameters that should not really be ref in C #, default parameters before C # had default parameters, inconsistent values ​​in default parameters ... ), but actually this is just a side effect of the fact that VS really does not know the language that was used to create the library, and even if that were the case, you would not want to see it - you are not indifferent to the interface open to you in C #, or something as close to him as possible.

Please note that these default parameters are really completely different from C # -C #, which are allowed during compilation on the client side (for example, changing the default parameters in library links does not change them in the user code until you recompile this code ), is not. As I said, VS does its best to get closer, but the CLR languages ​​can be very different.

+4
source

Source: https://habr.com/ru/post/972076/


All Articles