28.1.3 访问COM对象

C#4.0的主要改进之处如下:

❑不必再使用PIA(Primary Interop Assembly,主互操作程序集)和COM组件交互。在以前,每当发布一个COM组件时,如果还要让该COM组件可被托管的应用程序客户端使用,那么就还需要随该组件同时发布一个PIA。在C#4.0中,类型信息内嵌是默认行为,使用PIA已经成为一种选择,而非必须。那么,移除了对于PIA依赖的结果,就是更有利于版本的独立性了,也更加方便了开发(不需要特别生成PIA,以及类型信息内嵌)。另外发行包的大小也减少了,因为不必带着一堆臃肿的PIA走了。C#编译器会判断程序具体使用了哪一部分COM API,并只把这部分包装成IA(InteropAssembly,互操作程序集),直接加入到应用程序集里面。

❑编程更容易。因为COM方法返回的结果类型可以使用dynamic动态类型,而非Object类型。dynamic类型的变量直到运行时才会被检查,从而不必再进行显式类型转换。在进行COM Interop调用时,动态机制可以根据程序集中内嵌的类型,自动将返回的Object类型对象转换为dynamic类型的对象,也就是说,可以直接调用该动态对象的方法,而不需要进行显式类型转换。

我们通过一个例子,来观察具体是如何简化COM Interop调用的。在例子代码中,先新建一个Excel程序对象,然后通过该对象新建一份工作簿,并在工作簿的A1、B1两个单元格写入两个字符串,然后设置这两列为宽度自适应,步骤如下:

(1)保证系统中安装有Excel2007;

(2)在工程中添加对Microsoft.Office.Interop.Excel的引用,如图28-6所示;

(3)添加了引用后如图28-7所示。

28.1.3 访问COM对象 - 图1

图 28-6 添加对Microsoft.Office.Interop.Excel的引用

28.1.3 访问COM对象 - 图2

图 28-7 添加了对Microsoft.Office.Interop.Excel的引用

代码如代码清单28-5所示。

代码清单28-5 C#操作Excal对象


using System;

using Excel=Microsoft.Office.Interop.Excel;

using Word=Microsoft.Office.Interop.Word;

using System.Collections.Generic;

namespace ProgrammingCSharp4

{

class COMInteropSample

{

public static void Main()

{

var excelApp=new Excel.Application();

excelApp.Visible=true;

excelApp.Workbooks.Add();

Excel._Worksheet workSheet=(Excel.Worksheet)excelApp.ActiveSheet;

workSheet.Cells[1,"A"]="ID Number";

workSheet.Cells[1,"B"]="Current Balance";

workSheet.Columns[1].AutoFit();

workSheet.Columns[2].AutoFit();

}

}

}


注意看上述代码中加粗的两行代码:


workSheet.Columns[1].AutoFit();

workSheet.Columns[2].AutoFit();


早期版本的C#需要进行显式类型转换,因为workSheet.Columns[1]返回一个Object类型的对象,而AutoFit是Excel.Range对象的方法,因此需要进行下列的显式类型转换:


((Excel.Range)workSheet.Columns[1]).AutoFit();

((Excel.Range)workSheet.Columns[2]).AutoFit();


在C#4.0中,workSheet.Columns[1]返回的对象被自动转换为dynamic类型的对象,因此可以不必进行类型转换而直接调用它的AutoFit方法。