views:

109

answers:

4

How can I convert/dump an arraylist into a list? I'm using arraylist because I'm using the ASP.NET profiles feature and it looked like a pain to store List in profiles.

Note: The other option would be to wrap the List into an own class and do away with ArrayList.

http://www.ipreferjim.com/site/2009/04/storing-generics-in-asp-net-profile-object/

+10  A: 

The easiest way to convert an ArrayList full of objects of type T would be this (assuming you're using .NET 3.5 or greater):

List<T> list = arrayList.Cast<T>().ToList();

If you're using 3.0 or earlier, you'll have to loop yourself:

List<T> list = new List<T>(arrayList.Count);

foreach(T item in arrayList) list.Add(item);
Adam Robinson
In .NET 3.0 or earlier you could use `List<T> list = new List<T>( (T[])arrayList.ToArray() )`. This relies on the covariance of arrays in .NET, but is less efficient since it creates an extra copy of the data.
LBushkin
If the ArrayList is a mixture of object types use `OfType<T>()` instead of `Cast<T>()`. (.NET 3.5 or greater)
Jerod Houghtelling
@LBushkin, I couldn't get that to work without using the type overload of `ToArray` to return an `Array` base. Works all day long with `new List<T>((T[])arrayList.ToArray(typeof(T)))`
Marc
@Marc: Array covariance does not extend to arrays of value types. So you can write the statement: `string[] s = (string[])objectArray;` but you cannot write: `int[] i = (int[])objectArray;`. Is this perhaps the problem you see?
LBushkin
@Jerod: If the ArrayList were a mixture of incompatible types, it doesn't seem like the OP would have asked the question as he did. I'd rather present an answer to "How can I convert my ArrayList to `List<T>`?" (implying the *whole* list) with one that will give an exception when an incompatible type is present than a version that will silently filter the list when one is present.
Adam Robinson
@LBushkin, actually, no, I tried many types. The compiler is happy, as far as covariance is concerned, but the runtime implicit casting isnt.
Marc
Why is the arrayList.Count needed?
mgroves
@mgroves: It isn't *needed*, but it will ensure that the `List<T>` is initialized with that initial capacity, preventing it from possibly having to expand during the process of population.
Adam Robinson
@Marc: Yes, I understand my mistake now. Array covariance allows `string[]` to convert to `object[]` - but not the other way around. Which makes sense, since there's a conversion from `string` to `object`, but no conversion is possible from `object` to `string`. At compile time, the compiler can't tell if the `object[]` is really going to be a `string[]` so it allows the cast - but at runtime it, of course, fails. The runtime can't allows us to put a `string` into a `object[]`. The correct way to perform this conversion will require the overload that takes a `Type`. Sorry for the misdirection.
LBushkin
+2  A: 

You can use Linq if you are using .NET 3.5 or greater. using System.Linq;

ArrayList arrayList = new ArrayList();
arrayList.Add( 1 );
arrayList.Add( "two" );
arrayList.Add( 3 );

List<int> integers = arrayList.OfType<int>().ToList();

Otherwise you will have to copy all of the values to a new list.

Jerod Houghtelling
+1  A: 
ArrayList a = new ArrayList();

object[] array = new object[a.Count];

a.CopyTo(array);

List<object> list = new List<object>(array);

Otherwise, you'll just have to do a loop over your arrayList and add it to the new list.

Ryan Bennett
or turn this into a one liner, if he wanted object `new List<object>(a.ToArray());`
Marc
...seems a little long winded to me.
spender
@Marc: He could use List<T> and still keep it a oneliner by relying on [array covariance](http://msdn.microsoft.com/en-us/library/aa664572(VS.71%29.aspx) in C#: `new List<T>( (T[])a.ToArray() );`
LBushkin
A: 

This works in Framework <3.5 too:

Dim al As New ArrayList()
al.Add(1)
al.Add(2)
al.Add(3)
Dim newList As New List(Of Int32)(al.ToArray(GetType(Int32)))

C#

List<int> newList = new List<int>(al.ToArray(typeof(int)));
Tim Schmelter