什么是String 以及如何投射它?

我目前处于不幸的位置,不得不通过COM Interop从C#调用VBA宏。 宏返回一个字符串数组,看起来像:

Public Function Foo() As String() 

然后我试图在C#中转换为一个字符串数组,如下所示:

 var result = (string[])xlApp.Run("Foo", ... missing args ...) 

然后导致运行时错误:

无法将类型为’System.String [*]’的对象强制转换为’System.String []’。

有谁知道String [*]是什么,你是否知道如何将它转换为C#string []? 这个演员在我创建的一个简单的测试用例中工作。 我能看到的唯一区别是,在简单的情况下,我在VBA中的数组是字符串类型(0到5),而在更复杂的情况下,它是字符串类型(1到6)。 这可能是原因,如果是这样,我的VBA相当生疏 – 我该如何解决?

非常感谢,
乔恩

你的代码是

 var result = (string[])xlApp.Run("Foo", ... missing args ...); 

正如您所指出的,基于1的数组有不同的行为,在VB中使用从零开始的数组,您的代码确实有效。

你可以得到这样的数据

 var result = (Array)xlApp.Run("Foo", ... missing args ...); var stringsResult = result.Cast[]; 

这给你一个IEnumerable字符串

.NET支持这样的数组(下限不同于0),您可以使用这样的代码段创建一个:

 Array arr = Array.CreateInstance(typeof(string), new int[] { 5 }, new int[] {1}); 

将这样的数组转换为string []的最简单方法是(虽然,它复制数据,另一方面,这些只是引用,所以如果你的数组不是太长,你将不会获得巨大的性能):

 string[] x = new string[5]; Array.Copy(arr, 1, x, 0, 5); 

编辑:或使用更一般的方法:

 string[] x = new string[arr.GetLength(0)]; Array.Copy(arr, arr.GetLowerBound(0), x, 0, arr.GetLength(0)); 

Edit2:它看起来像是使用lowerbounds的数组!= 0适用于罚款,如果有超过1个维度,你可以在这里阅读更多内容,其中Jon Skeet似乎回答了为什么会发生这种情况。

编辑3:根据djna的评论,使回复不那么模糊。 这是你可以从方法返回的对象中获取string []的方法,它不能直接转换为string [],因为它有lowerBound!= 0:

 Array arr = (Array)xlApp.Run("Foo", ... missing args ...); //Here I assume that .Run() method is returning object, or something that has to be casted to Array. string[] result = new string[arr.GetLength(0)]; Array.Copy(arr, arr.GetLowerBound(0), result, 0, arr.GetLength(0)); // Here data is copied, but only references in this scenario