FSharp和Microsoft Office PIA

时间:2016-04-06 09:41:21

标签: f# ms-office

我正在使用FSharp的Microsoft Office PIA。当我尝试从Microsoft Word获取SynonymInfo时:

#r "Office.dll"
#r "Microsoft.Office.Interop.Word.dll"
open Microsoft.Office.Interop.Word

let application = ApplicationClass()
let synonymInfo = application.SynonymInfo("bracket")
let meaningList = synonymInfo.MeaningList :?> string[]

我得到了这个例外:

  

System.InvalidCastException:无法转换类型的对象   ' System.String [*]'输入' System.String []'。

来自COM对象的转换是否导致此问题?我怎样才能正确地投射?是元组的*吗?如果是这样,字符串[,]也不起作用......

由于

1 个答案:

答案 0 :(得分:5)

Office互操作返回一个数组,其中索引不是从0开始,而是(可能)从1开始(旧的Visual Basic时间!)这就是*String[*]类型中的含义。

您甚至可以从F#创建此类数组:

let array = System.Array.CreateInstance(typeof<int>, [| 10 |], [| 1 |]) 

不幸的是,Int32[*]Int32[]的类型不同,因此投射失败:

// System.InvalidCastException: Unable to cast 
// object of type 'System.Int32[*]' to type 'System.Int32[]'.
array :?> int[]

您需要以另一种方式将1索引数组中的数据转换为其他结构。我的示例中的array类型实现了非泛型IEnumerable,因此您应该能够编写如下内容:

array |> Seq.cast<int> |> Array.ofSeq

如果您的案例中的值类型为obj,则您需要先将其强制转换为接口:

(thing :?> IEnumerable) |> Seq.cast<string> |> Array.ofSeq

您还可以使用以下内容获取具有索引值对的数组:

[| for i in array.GetLowerBound(0) .. array.GetUpperBound(0) ->
     i, array.GetValue(i) :?> int |]