views:

523

answers:

4

I'd like to create an array from range of values within an ArrayList but am getting the error "At least one element in the source array could not be cast down to the destination array type".

Why should the following fail, and what would you do instead?

int[] ints = new int[] { 1, 2, 3 };
ArrayList list = ArrayList.Adapter(ints);
int[] mints = (int[])list.GetRange(0, 2).ToArray(typeof(int));
A: 

If you can work with arrays, perhaps just Array.Copy:

    int[] ints = new int[] { 1, 2, 3 };
    int[] mints = new int[2];
    Array.Copy(ints, 0, mints, 0, 2);

Alternatively, it looks like you'll have to create an array and loop/cast.

(for info, it works fine "as is" on 2.0 - although you'd use List<int> instead)

Marc Gravell
A: 

This works fine in DotNet 2.0, so I would suggest starting by comparing the disassembled Framework code to see what the difference is.

In 2.0, calling ArrayList.Adapter() returns an ArrayList.IListWrapper (which inherits from ArrayList) which simply wraps an IList (in your case, an array of type int[]). Calling ToArray on an IListWrapper calls IList.CopyTo on the underlying array.

Obviously this must be implemented differently in 1.1 because the way it is set up in 2.0, it can't fail.

Snarfblam
A: 

Normally, this should just work:

(int[])list.GetRange(0, 2).ToArray(typeof(int));

Since GetRange just returns a new ArrayList.

Are you sure that your ArrayList just contains integers , and nothing else ?

I can't test it in .NET 1.1, but I suppose that: - your arraylist contains elements that are of some other type then int. - the ArrayList.Adapter method is the originator of the problem.

Also, why don't you initialize the ArrayList like this:

ArrayList l = new ArrayList ( new int[] {0, 1, 2, 3, 4, 5});

?

Frederik Gheysels
I think the point is that the posted code shouldn't fail, and the fact that it does indicates a strong possibility of inexplicable exceptions in different circumstances.
Snarfblam
+3  A: 

This is a known bug in .NET 1.1, and has been fixed in the .NET 2.0.

The behavior of GetRange is broken in this release. If you try to list the content of the return value using the parameterless ToArray() for the ArrayList wrapper instance returned by GetRange, you'll see that it contains null references and other inconsistent values.

See posts from December 2004 here and here, in the BCL Team Blog.

Jerome Laban