.NET 4.0 Excel Interop 与动态集合相关的问题

发布于 2024-10-14 03:12:30 字数 534 浏览 3 评论 0原文

在 Excel 中,您可以使用 XValues 从系列对象返回动态数组 System.Object[*]。在 .NET 3.5 中,您可以通过将其转换为数组来访问该对象中的元素,即:

var values = (Array)series.XValues;

在 .NET 4.0 中,这不再起作用,并且消息

“无法将“System.Object[*]”类型的对象转换为“System.Object[]”类型”

给出

。有什么想法吗?以下不起作用:

  • 将其转换为动态。
  • 将其转换为 System.Object[*]
  • 只需将对象放入 foreach 循环中即可。
  • 尝试使用 values[1] 直接访问该值,在转换为动态时也不会。

然而,数组内的值确实显示在调试器中。

In Excel you can return a dynamic array System.Object[*], from a series object using XValues. In .NET 3.5 you can access the elements in this object by casting it to and array, i.e.:

var values = (Array)series.XValues;

In .NET 4.0, this no longer works, and the message

"Unable to cast object of type 'System.Object[*]' to type 'System.Object[]'"

is given.

Any ideas? The following doesn't work:

  • Casting it as dynamic.
  • Casting it to a System.Object[*].
  • Just placing the object in a for each loop.
  • Trying to access the value directly using values[1], neither when cast as a dynamic.

The values inside the array do show up in the debugger however.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

怪我鬧 2024-10-21 03:12:30

上面的答案很有用,但没有解决如何转换为数组的问题。

在 4.0 之前的 .Net 版本中,简单的转换就可以工作。

在 C# 4.0 中必须使用

System.Array a = (System.Array)((object)  returnedObject ); // note order of brackets

see
http://blogs .msdn.com/b/mshneer/archive/2010/06/01/oh-that-mysteriously-broken-visiblesliceritemslist.aspx

The answer above is useful but does not address the issue of how to cast to Array.

Under .Net versions before 4.0 a simple cast would work.

in C# 4.0 one must use

System.Array a = (System.Array)((object)  returnedObject ); // note order of brackets

see
http://blogs.msdn.com/b/mshneer/archive/2010/06/01/oh-that-mysteriously-broken-visiblesliceritemslist.aspx

懒的傷心 2024-10-21 03:12:30

.NET 中有两种不同类型的数组,一维“向量”和多维数组。您得到了后者,一个等级为 1 的多维数组。如果非托管代码返回下限不为 0 的 SAFEARRAY,就会发生这种情况。

您可以使用 Array.GetValue() 读取数组的内容。或者像这样转换它:

    private static object[] ConvertArray(Array arr) {
        int lb = arr.GetLowerBound(0);
        var ret = new object[arr.GetUpperBound(0) - lb + 1];
        for (int ix = 0; ix < ret.Length; ++ix) {
            ret[ix] = arr.GetValue(ix + lb);
        }
        return ret;
    }

测试:

    var native = Array.CreateInstance(typeof(object), new int[] { 42 }, new int[] { 1 });
    var dotnet = ConvertArray(native);

注意:在 .NET 4.0 及更高版本中,当您使用某些 COM 类型库(尤其是 Office)时,可能会遇到问题。该属性或方法可能返回包含数组的变体。在您的 C# 程序中最终成为动态。在这种情况下,C# 编译器不会生成正确的绑定器代码。通过首先转换为(对象),然后转换为(数组)来解决这个问题。

There are two distinct kind of arrays in .NET, a one dimensional 'vector' and multidimensional arrays. You got the latter back, a multidimensional array with a rank of 1. This will happen if the unmanaged code has returned a SAFEARRAY whose lower-bound isn't 0.

You can read the content of the array with Array.GetValue(). Or convert it, like this:

    private static object[] ConvertArray(Array arr) {
        int lb = arr.GetLowerBound(0);
        var ret = new object[arr.GetUpperBound(0) - lb + 1];
        for (int ix = 0; ix < ret.Length; ++ix) {
            ret[ix] = arr.GetValue(ix + lb);
        }
        return ret;
    }

Test:

    var native = Array.CreateInstance(typeof(object), new int[] { 42 }, new int[] { 1 });
    var dotnet = ConvertArray(native);

NOTE: you may have a problem in .NET 4.0 and up when you some COM type libraries, Office in particular. The property or method may return a variant that contains an array. Ends up as dynamic in your C# program. The C# compiler does not generate the proper binder code in that case. Work around that by casting first to (object), then to (Array).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文