When I Tried to return a Array in VFP9 languaje COM/DLL to my .net c# project I received a System.Object[*] array and I can not cast to System.Object[] (Without asterisk).
+3
A:
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);
Timwi
2010-09-16 22:29:51
Great, this works, but if you have thousands of items, you think?'ll Keep testing with queries or grades.
Cheva
2010-09-16 22:48:11
googling I find a VFP instruction for this from VFP source code: the function ComArray(This.newArray, 10) that pass to based zero. the inverse method
Cheva
2010-09-20 19:53:58
+4
A:
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);
Thomas Levesque
2010-09-16 22:33:57
Somehow I never think of the solutions which are shorter but much slower. I realise that in most cases the performance penalty is insignificant...
Timwi
2010-09-16 22:35:34
Does this work because the `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 just`ToArray()` ) instead? It would remove the need for a cast from `object` to `object`.
Callum Rogers
2010-09-16 22:47:21
Indeed, it will be a bit slower. When the source sequence implements `ICollection<T>`, `ToArray` takes advantage of that, but arrays with non-zero bounds only implements the non-generic `ICollection`...
Thomas Levesque
2010-09-16 22:48:47
@Myself: You can't just use `ToArray()` or `Select()` because `Array` only implements the non-generic `IEnumerable` and they both require `IEnumerable<T>`. +1 for this answer for cleverness.
Callum Rogers
2010-09-16 23:01:54