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

问题描述 投票:0回答:4

当我尝试将 VFP9 语言 COM/DLL 中的

Array
返回到我的 .NET C# 项目时 我收到一个
System.Object[*]
数组,但无法转换为
System.Object[]
(没有星号)。

c# interop casting visual-foxpro
4个回答
9
投票

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

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

如果您需要重新创建

System.Object[*]
将其传回 VFP,您可以使用 Array.CreateInstance 方法的
this 重载

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);

6
投票

不幸的是,你不能直接施放它。但是,您可以创建一个类型为

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);

5
投票

我也有类似的问题。从互操作程序集中获取一个作为

dynamic
对象的数组,也从索引一开始。当我尝试将其转换为
Array
对象时,我收到了相同的错误消息。
按照其他答案的建议进行操作并没有成功。由于一个奇怪的原因,即使读取
Length
属性也会引发异常。
我找到了this答案,并且成功了。
显然,如果你使用 C# 4.0,你必须先将
dynamic
转换为
object
,然后才能将其转换为
Array
。在 .NET 的早期版本中,您可以直接进行投射。
这是解释原因。


0
投票

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

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

public static Array ConvertToZeroBaseIndexes(this Array arrayValue)
{
    // If it's already a zero-based array, just return it
    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;
}
© www.soinside.com 2019 - 2024. All rights reserved.