如何将 System.Object[*] 转换为 System.Object[]

发布于 2024-09-19 06:45:07 字数 151 浏览 9 评论 0原文

当我尝试将 VFP9 语言 COM/DLL 中的 Array 返回到我的 .NET C# 项目时 我收到一个 System.Object[*] 数组,但无法转换为 System.Object[] (不带星号)。

When I Tried to return an Array in VFP9 language COM/DLL to my .NET C# project
I receive a System.Object[*] array and I can not cast to System.Object[] (Without asterisk).

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

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

发布评论

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

评论(4

迷路的信 2024-09-26 06:45:07

Timwi 的解决方案应该可以正常工作。您可以使用 Linq 做一些简单的事情:

object[] newArray = sourceArray.Cast<object>().ToArray();

如果您需要重新创建 System.Object[*] 以将其传递回 VFP,您可以使用 Array.CreateInstance 方法的“nofollow noreferrer”>此重载

public static Array CreateInstance(
    Type elementType,
    int[] lengths,
    int[] lowerBounds
)

您可以按如下方式使用它:

object[] normalArray = ...

// create array with lower bound of 1
Array arrayStartingAt1 =
    Array.CreateInstance(
        typeof(object),
        new[] { normalArray.Length },
        new[] { 1 });

Array.Copy(normalArray, 0, arrayStartingAt1, 1, normalArray.Length);

Timwi's solution should work fine. You can do something a bit simpler using Linq:

object[] newArray = sourceArray.Cast<object>().ToArray();

In case you need to recreate a System.Object[*] to pass it back to VFP, you can use this overload of the Array.CreateInstance method:

public static Array CreateInstance(
    Type elementType,
    int[] lengths,
    int[] lowerBounds
)

You can use it as follows:

object[] normalArray = ...

// create array with lower bound of 1
Array arrayStartingAt1 =
    Array.CreateInstance(
        typeof(object),
        new[] { normalArray.Length },
        new[] { 1 });

Array.Copy(normalArray, 0, arrayStartingAt1, 1, normalArray.Length);
各自安好 2024-09-26 06:45:07

不幸的是,你不能直接投射它。但是,您可以创建一个 object[] 类型的新数组并复制数据。像...

Array sourceArray = ...;

if (sourceArray.Rank != 1)
    throw new InvalidOperationException("Expected a single-rank array.");

object[] newArray = new object[sourceArray.Length];
Array.Copy(sourceArray, sourceArray.GetLowerBound(0),
           newArray, 0, sourceArray.Length);

Unfortunately, you cannot cast it directly. You can, however, create a new array of type object[] and copy the data over. Something like...

Array sourceArray = ...;

if (sourceArray.Rank != 1)
    throw new InvalidOperationException("Expected a single-rank array.");

object[] newArray = new object[sourceArray.Length];
Array.Copy(sourceArray, sourceArray.GetLowerBound(0),
           newArray, 0, sourceArray.Length);
枫以 2024-09-26 06:45:07

我有类似的问题。从互操作程序集中获取了一个作为 dynamic 对象的数组,同样从索引一开始。当我尝试将其转换为 Array 对象时,我得到了相同的结果错误消息。
按照其他答案的建议进行操作并没有成功。由于奇怪的原因,即使读取 Length 属性也会引发异常。
我发现这个答案,它起作用了。
显然,如果您使用 C# 4.0,则必须先将 dynamic 转换为 object,然后才能将其转换为 Array。在 .NET 的早期版本中,您可以直接进行转换。
这是说明为什么。

I had a similar issue. Got an array as a dynamic object from an interop assembly, also starting from index one. When I tried to convert this into an Array object, I got the same error message.
Doing as the other answers suggest did not work. For a strange reason, even reading the Length property raised the exception.
I found this answer, and it worked.
Apparently, if you use C# 4.0, you have to cast the dynamic to object first, then you can convert it to Array. In prior versions of .NET you can cast directly.
Here is an Explanation why.

雨的味道风的声音 2024-09-26 06:45:07

我在从 API 动态读取数组时遇到了这个问题,该 API 从支持数组索引任意范围(IEC 61131-3 PLC 编程语言数组)的非 .NET 平台返回数据。该平台还支持多维数组,每个维度都有不同的下限

这是我编写的用于转换数组的代码。它适用于具有任意下限的一维和多维数组,将它们转换为具有相同基础类型、等级和形状的 .NET 数组。

public static Array ConvertToZeroBaseIndexes(this Array arrayValue)
{
    // If it's already a zero-based array, just return it instead of doing a pointless array copy
    if ((arrayValue.Rank == 1 && arrayValue.GetLowerBound(0) == 0) ||
        Enumerable.Range(0, arrayValue.Rank).All(dimension => arrayValue.GetLowerBound(dimension) == 0))
    {
        return arrayValue;
    }

    Type? arrayElementType = arrayValue.GetType().GetElementType();
    if (arrayElementType == null) throw new InvalidOperationException("Cannot convert array of unknown type");

    var dimensionSizes = Enumerable.Range(0, arrayValue.Rank)
        .Select(dimension => arrayValue.GetUpperBound(dimension) - arrayValue.GetLowerBound(dimension) + 1)
        .ToArray();

    Int32 elementCount = dimensionSizes.Aggregate((product, dimensionSize) => product * dimensionSize);

    var target = Array.CreateInstance(arrayElementType, dimensionSizes);
    Array.Copy(arrayValue, target, elementCount);

    return target;
}

I've encountered this issue when reading arrays dynamically from an API which returns data from a non-.NET platform which supports arbitrary ranges for array indexes (IEC 61131-3 PLC programming language arrays). This platform also supports multi-dimensional arrays with different lower bounds for each dimension!

Here's the code I wrote to convert the arrays. It works for both 1d and multi-dimensional arrays with arbitrary lower bounds, converting them to a .NET array of the same underlying type, rank, and shape.

public static Array ConvertToZeroBaseIndexes(this Array arrayValue)
{
    // If it's already a zero-based array, just return it instead of doing a pointless array copy
    if ((arrayValue.Rank == 1 && arrayValue.GetLowerBound(0) == 0) ||
        Enumerable.Range(0, arrayValue.Rank).All(dimension => arrayValue.GetLowerBound(dimension) == 0))
    {
        return arrayValue;
    }

    Type? arrayElementType = arrayValue.GetType().GetElementType();
    if (arrayElementType == null) throw new InvalidOperationException("Cannot convert array of unknown type");

    var dimensionSizes = Enumerable.Range(0, arrayValue.Rank)
        .Select(dimension => arrayValue.GetUpperBound(dimension) - arrayValue.GetLowerBound(dimension) + 1)
        .ToArray();

    Int32 elementCount = dimensionSizes.Aggregate((product, dimensionSize) => product * dimensionSize);

    var target = Array.CreateInstance(arrayElementType, dimensionSizes);
    Array.Copy(arrayValue, target, elementCount);

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