了解COM c#接口

本文关键字:接口 COM 了解 | 更新日期: 2023-09-27 18:12:38

_Document接口有一个签名如下的方法:

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

我理解有困难的几点:

  1. ref参数不能有默认值
  2. 默认值必须是常数,Type.Missing不是。
  3. 当调用这个方法时,我可以使用Close(false) -通常一个ref参数需要一个可分配的变量?
  4. 在Visual Studio中导航到Type的定义时,它带我到_Document。类型属性,但它没有名为Missing的属性。这是VS中的一个bug吗?

谢谢你的解释

了解COM c#接口

问题是,InterOp库实际上不是用c#编写的,也不必遵守c#的规则。它唯一必须是有效的IL。

Visual Studio元数据查看器会尽力以您选择的语言(在本例中为c#)显示元数据,因为它通常比使用IL代码更具可读性。

这可以误导在某些情况下(例如ref参数实际上并不需要ref年代在c#中,缺省参数在c#缺省参数之前,不恒定值缺省参数…),但它确实只是一个副作用的事实和不知道的语言是用于构建图书馆,即使那样,你不想看到,你关心的接口暴露于你在c#中,或尽可能接近的东西。

请注意,这些默认参数实际上与c#的工作方式完全不同- c#是在客户端编译时解决的(例如,更改引用库中的默认参数不会更改用户代码中的默认参数,直到您重新编译该代码),这些不是。正如我所说,VS尽其所能地近似,但CLR语言确实可以非常不同。

这是c#第4版引入的特性。它不是COM互操作代码所独有的,您也可以在自己的代码中获得它。试试这个:

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

触发此行为的是[可选]属性。一直存在,但在c#中从未特别有用。不像其他语言,比如VB。. NET和c++/CLI。从c# v4开始,它以不同的方式解释属性,编译器将硬编码Type。缺少对象参数类型的可选值。尝试将参数类型更改为string,并注意默认值变得不同。

这当然不是很漂亮,Type。Missing是普通c#代码中对象的一个相当奇怪的默认值。每个人都会期望null。然而,它是非常实用的,在4之前的版本中,用c#编写Office互操作代码是一个相当可怕的练习。当公司做这样的事情时,他们可能会陷入麻烦,顺便说一句,如果Neelie Kroes听到风声,她会让微软为此支付10亿欧元的罚款:)