C#中的MS Word自动化 - 无法将类型为 'System.String[*]' 的对象强制转换为类型 'System.String[]'

10

我使用以下代码来获取一个MS Word 2007文档(.docx)中所使用的标题的字符串数组:

dynamic arr = Document.GetCrossReferenceItems(WdReferenceType.wdRefTypeHeading);

通过调试器,我看到arr被动态分配为一个包含文档中所有标题(约40个条目)的字符串数组。 迄今为止一切顺利。

然后,我想访问这些字符串,但无论我如何操作,都会得到以下异常:

InvalidCastException: 
           Unable to cast object of type 'System.String[*]' to type 'System.String[]'.

我尝试了不同的方法来访问字符串:

通过索引:

String arr_elem = arr[1];

通过将其转换为IEnumerable:

IEnumerable list = (IEnumerable)arr;

通过使用一个简单的 foreach 循环:

foreach (String str in arr)
{
   Console.WriteLine(str);
}

然而,无论我尝试什么,最终都会得到如上所示的相同异常。

有人能解释一下我错过了什么/我做错了什么吗?特别是String[*] - 它是什么意思?


我已经向微软报告了这个错误:https://connect.microsoft.com/VisualStudio/feedback/details/684538/dynamic-incorrectly-treats-1d-arrays-as-vectors - Marc Gravell
3个回答

8

string[]是一个向量 - 一个一维的、以0为基础的数组。然而,string[*]是一个常规数组,只是恰好有一个维度。基本上,你需要将它作为Array处理,并且要么复制数据,要么使用Array API而不是string[] API。

这与typeof(string).MakeArrayType()(向量)和typeof(string).MakeArrayType(1)(一个一维非向量)之间的区别相同。


你认为动态运行时试图像访问向量一样访问数组是一个错误吗? - Gabe
@Gabe - 是的:https://connect.microsoft.com/VisualStudio/feedback/details/684538/dynamic-incorrectly-treats-1d-arrays-as-vectors - Marc Gravell

7

尝试

object arr_r = Document.GetCrossReferenceItems(WdReferenceType.wdRefTypeHeading);
Array arr = ((Array) (arr_r));

string myHeading = (string) arr.GetValue(1);

5
问题在于您在一个显然不适用的情况下使用了 "dynamic"。当动态运行时看到一个1D数组时,它会认为它是一个向量,并尝试将其索引或枚举为向量。这是一种罕见情况,您有一个不是向量的1D数组,因此必须将其处理为 "Array":
Array arr = (Array)(object)Document.
            GetCrossReferenceItems(WdReferenceType.wdRefTypeHeading);
// works
String arr_elem = arr.GetValue(1);
// now works
IEnumerable list = (IEnumerable)arr; 
// now works
foreach (String str in arr)
{
    Console.WriteLine(str);
}

谢谢您的解释 :) 您的第一行代码抛出了一个 InvalidCastException 异常:无法将类型为 'System.String[*]' 的对象强制转换为类型 'System.String[]'。 - Lasse Christiansen
@sw_lasse:哎呀,你说得对。我修复了它。我的版本在C# 3.0中可以工作,但由于非标准数组的动态访问中的明显错误,在4.0中出现了故障。 - Gabe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接