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).
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);
Cast
can simply iterate over the array using an IEnumerator instead of worrying where the array starts? If so couldn't you just use Select(x => x).ToArray()
(or even justToArray()
) instead? It would remove the need for a cast from object
to object
. –
Melioration ICollection<T>
, ToArray
takes advantage of that, but arrays with non-zero bounds only implements the non-generic ICollection
... –
Carborundum Array
implements IEnumerable
–
Carborundum ToArray()
or Select()
because Array
only implements the non-generic IEnumerable
and they both require IEnumerable<T>
. +1 for this answer for cleverness. –
Melioration public int ReadFPGA( out object[*] param, ...)
in a dll, where the run-time version is 4.0.x? The project and all other dll is 4.5.2., only this one is 4.0.x. –
Seymore 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);
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.
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;
}
© 2022 - 2024 — McMap. All rights reserved.
Object[*]
? Do you mean anObject*
as in an unmanaged pointer to an Object array? – MeliorationSystem.Array
s) that don't start at zero? As in they would give anIndexOutOfRangeException
if you tried to access the zeroth element? How is this useful? – MeliorationArray.GetValue()
, and yes, you would get theIndexOutOfRangeException
. The reason the CLR supports such arrays is because of VB.NET. – Phallic