使用COM 风格的编程接口
假设不直接使用 COM 库。不创建自己的包装。那么更可能的是使用 COM 风格的编程接口。这是由于如今很多开发商公布应用程序时。提供了首选的互操作程序集(Primary Interop Assemblies)。这是预先创建的 COM 包装,因此,我们就不须要再自己考虑用 TlbImp.exe 来创建包装了。
注意
很多其它有关首选的互操作程序集的内容。能够在 MSDN 上找到。http://msdn.microsoft.com/en-us/library/aax7sdch.aspx 。
尽管首选的互操作程序集本质上就是 .NET 程序集,可是,通常有一些特殊的地方须要注意。比方:
某些数组和集合常常从 1 開始,而不是 0。
常常有一些方法,会有大量的可选參数;
很多属性和方法会返回对象(object)类型,产生的结果对象须要强制转换成真正的类型;
COM 类包括非托管的资源。须要处理(dispose)。然而,这些类没有实现标准的 .NET IDisposable 接口,因此。在 F# 的 use 绑定中就不能使用;只是。我们可以使用 F# 的对象表达式非常easy地就实现了 IDisposable。
F# 和 COM 进行交互与 C# 的关键不同在于,我们必须总是要创建对象的实例。而非接口。这听趚有点奇怪,可是,在 COM 库中,每个对象通常都有一个接口,有一个实现接口的类。在 C# 中,假设使用keyword new 尝试创建 COM 接口的实例,的COM posablesable 编译器会自己主动定向到(redirect)调用相应的类,而在 F#中就不是这样。
与 Microsoft Office 交互可能是使用 COM 风格库的最常见理由。
以下的清单是读取 Excel 电子表格的信息。
open System
open Microsoft.Office.Interop.Excel
let main() =
// initalize an excel application
let app = new ApplicationClass()
// load a excel work book
let workBook =app.Workbooks.Open(@"Book1.xls",ReadOnly =
true)
// ensure work book is closed corectly
use bookCloser ={ new IDisposable with
member x.Dispose() = workBook.Close() }
// open the first worksheet
let worksheet =workBook.Worksheets.[1] :?> _Worksheet
// get the A1 ceel and all surround cells
let a1Cell =worksheet.Range("A1")
let allCells =a1Cell.CurrentRegion
// load all cells into a list of lists
let matrix =
[ for row inallCells.Rows ->
let row = row:?> Range
[ for cell inrow.Columns ->
let cell = cell :?
> Range
cell.Value2] ]
// close the workbook
workBook.Close()
// print the matrix
printfn "%A" matrix
do main()
注意这个演示样例是怎样处理我们前面提到的特殊地方的。我们实现了 IDisposable 并把它绑定到 bookCloser,保证即使在出错的情况下也能关闭工作簿。Open 方法有 15 个參数。可是。我们仅仅用了两个:.Open(@"Book1.xls", ReadOnly = true)。第一个工作表的索引 1:workBook.Worksheets.[1];终于,每一行必须被强制转换起来(upcast)能够使用:let row = row :?> Range。