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

- 16,053
- 9
- 49
- 91

- 331
- 5
- 12
-
What is an `Object[*]`? Do you mean an `Object*` as in an unmanaged pointer to an Object array? – Callum Rogers Sep 16 '10 at 22:24
-
2@Callum: No, it is a System.Array with a non-zero starting index. – Timwi Sep 16 '10 at 22:27
-
Yes @Callum, so How I can work with this? – Cheva Sep 16 '10 at 22:31
-
@Timwi: Yikes, you can have arrays (as in real `System.Array` s) that don't start at zero? As in they would give an `IndexOutOfRangeException` if you tried to access the zeroth element? How is this useful? – Callum Rogers Sep 16 '10 at 22:33
-
@Cheva: So it is a pointer problem then... do you know the size of the array or is it null terminated? – Callum Rogers Sep 16 '10 at 22:36
-
@Callum: Yes, although the only way to access such an array in C# is to use `Array.GetValue()`, and yes, you would get the `IndexOutOfRangeException`. The reason the CLR supports such arrays is because of VB.NET. – Timwi Sep 16 '10 at 22:39
-
(Also, I doubt Cheva knew what they were saying when they answered your question with “yes”. I don’t think it’s a pointer problem.) – Timwi Sep 16 '10 at 22:41
-
@Timwi: That's why I haven't answered. I'm guessing this VFP language uses arrays starting at 1 or some other value. – Callum Rogers Sep 16 '10 at 22:42
-
@Callum Rogers, hopefully it isn't "some other value"... An array that starts at 42 would be really weird ;) (although you can create such an array in C#...) – Thomas Levesque Sep 16 '10 at 22:52
-
(I have once had a reasonable usecase for an array that starts at −1.) – Timwi Sep 16 '10 at 23:08
3 Answers
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);

- 7,300
- 10
- 40
- 88

- 286,951
- 70
- 623
- 758
-
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 Sep 16 '10 at 22:35
-
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 Sep 16 '10 at 22:47
-
Indeed, it will be a bit slower. When the source sequence implements `ICollection
`, `ToArray` takes advantage of that, but arrays with non-zero bounds only implements the non-generic `ICollection`... – Thomas Levesque Sep 16 '10 at 22:48 -
@Callum Rogers, yes, exactly. `Array` implements `IEnumerable` – Thomas Levesque Sep 16 '10 at 22:49
-
-
@Myself: You can't just use `ToArray()` or `Select()` because `Array` only implements the non-generic `IEnumerable` and they both require `IEnumerable
`. +1 for this answer for cleverness. – Callum Rogers Sep 16 '10 at 23:01 -
What happens if I have a method like `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. – minus one Oct 17 '17 at 15:18
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);

- 65,159
- 33
- 165
- 230
-
Great, this works, but if you have thousands of items, you think? 'll Keep testing with queries or grades. – Cheva Sep 16 '10 at 22:48
-
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 Sep 20 '10 at 19:53
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.

- 733
- 7
- 16
-
Thanks for posting this! All the other stuff doesn't work with a dynamic. – Marty Jan 04 '17 at 12:53
-
Up-voted. Very good information which I also discovered now myself. See so-called [thread II](https://stackoverflow.com/questions/23366984/) for more. – Jeppe Stig Nielsen Oct 26 '17 at 16:11