当我尝试将 VFP9 语言 COM/DLL 中的
Array
返回到我的 .NET C# 项目时
我收到一个 System.Object[*]
数组,但无法转换为 System.Object[]
(没有星号)。
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);
不幸的是,你不能直接施放它。但是,您可以创建一个类型为
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);
我在从 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;
}