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

时间:2009-09-04 13:18:38

标签: c# vba com interop

我目前处于不幸的位置,不得不通过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相当生疏 - 我该如何解决?

非常感谢,
乔恩

2 个答案:

答案 0 :(得分:5)

.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个维度,你可以阅读更多here,其中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

答案 1 :(得分:1)

您的代码是

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

正如您所指出的,基于1的数组有不同的行为,在VB中使用从零开始的数组,您的代码可以正常工作。

你可以获得这样的数据

var result = (Array)xlApp.Run("Foo", ... missing args ...);

var stringsResult = result.Cast<string>[];

这为您提供了IEnumerable of string