Understand COM c# interfaces

谁说我不能喝 提交于 2019-12-04 05:52:56

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

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
    }
}

It is the [Optional] attribute that triggers this behavior. Been around forever but was never particularly useful in C# before. Unlike other languages like VB.NET and C++/CLI. Starting with C# v4, it interprets the attribute differently and the compiler will hard-code Type.Missing as the optional value for an argument type of object. Try changing the argument type to, say, string and note that the default becomes different. Null, as you'd expect.

This isn't very pretty of course, Type.Missing is a rather odd default value for object in normal C# code. Everybody would expect null instead. It is however very practical, writing Office interop code in C# in versions previous to 4 was a rather dreadful exercise. Companies can get into trouble when they do stuff like this btw, if Neelie Kroes gets wind of it she'd get Microsoft to pay a billion Euro fine for that :)

The thing is, the InterOp library isn't actually written in C#, and doesn't have to conform to C#'s rules. The only thing it has to be is valid IL.

The Visual Studio metadata viewer tries its best at showing you the metadata in the language of your choosing (in this case, C#), because it's usually a lot more readable than using the IL code.

This can be misleading in some cases (e.g. the ref parameters that don't actually have to be refs in C#, default parameters before C# had default parameters, non-constant values in default parameters...), but it really is just a side effect of the fact that VS doesn't really know the language that was used to build the library, and even if it did, you wouldn't want to see that - you care about the interface exposed to you in C#, or something as close to it as possible.

Note that those default parameters actually work completely differently from C#'s - C#'s are resolved at compile time on client-side (e.g. changing default parameters in referenced libraries will not change them in user code until you recompile that code too), these are not. As I said, VS does its best to approximate, but the CLR languages can be very different indeed.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!