Generic List Converter Snippet

A useful little class that you might find you need someday. It converts a weakly-typed list (like an IList of items) into a strongly typed one based on the type you feed it.

It's super simple to use. For example let's say you get back an IList<People> from some service (a data service, web service, etc.) but really need it to be a List<People>. You can just use this class to convert it for you.

I know, silly little example but just something for your code snippets that you can squirrel away for a rainy day.

    1 public class ListToGenericListConverter<T>

    2 {

    3     /// <summary>

    4     /// Converts a non-typed collection into a strongly typed collection.  This will fail if

    5     /// the non-typed collection contains anything that cannot be casted to type of T.

    6     /// </summary>

    7     /// <param name="listOfObjects">A <see cref="ICollection"/> of objects that will

    8     /// be converted to a strongly typed collection.</param>

    9     /// <returns>Always returns a valid collection - never returns null.</returns>

   10     public List<T> ConvertToGenericList(IList listOfObjects)

   11     {

   12         ArrayList notStronglyTypedList = new ArrayList(listOfObjects);

   13         return new List<T>(notStronglyTypedList.ToArray(typeof(T)) as T[]);

   14     }

   15 }

Published Tuesday, May 08, 2007 3:29 PM by Bil Simser
Filed under:

Comments

# re: Generic List Converter Snippet

Tuesday, May 08, 2007 6:54 PM by Wilco Bauwer

FWIW, I think this will result in copying the elements three times. ;) From listOfObjects to notStronglyTypedList, to a temporary array to the typed list that gets returned. Alternative version:

List<T> Conv...(IList listOfObjects) {

 List<T> items = new List<T>();

 foreach (T obj in listOfObjects) {

   items.Add(obj);

 }

 return items;

}

# re: Generic List Converter Snippet

Wednesday, May 09, 2007 4:57 AM by Muntedhar Alhakim

Can always use AddRange()...

# re: Generic List Converter Snippet

Wednesday, May 09, 2007 7:29 AM by commenter

I take it by IList<People> you mean "an IList containing People objects".

# re: Generic List Converter Snippet

Wednesday, May 09, 2007 8:53 AM by Casey Barton

A major benefit of Wilco's approach is that you can accept an IEnumerable instead of an IList, which makes it much more generally useful.

# re: Generic List Converter Snippet

Wednesday, May 09, 2007 12:58 PM by Scott Modesto

Did this come from Billy McCafferty's article on nHibernate?

http://www.codeproject.com/aspnet/NHibernateBestPractices.asp

# re: Generic List Converter Snippet

Wednesday, May 09, 2007 2:48 PM by cpon

I also have an alternative which will twice.

List<T> Conv...(IList listOfObjects) {

T[] temp = new T[ listOfObjects.Count ];

listOfObjects.CopyTo( temp, 0 );

return new List<T>( temp );

}

# re: Generic List Converter Snippet

Thursday, May 10, 2007 7:14 AM by Bil Simser

@Scott: Yes, looking at it now I see it is. It was something in our codebase around NHibernate which I thought was useful but yes, it came from that article. Although its interesting now to see the alternatives. Might be interesting to compare and see what's the most efficient.

# re: Generic List Converter Snippet

Thursday, May 10, 2007 2:53 PM by James Curran

Well, first of all, you API is a bit nasty.  It use this, we'd have to write:

ArrayList myList = new ArrayList(); //...

ListToGenericListConverter<int> conv = new ListToGenericListConverter<int>()

List<int> yourList = conv.ConvertToGenericList(myList);

which seems a bit extreme.

You probably meant to make the method static, inwhich case it become just:

List<int> yourList = ListToGenericListConverter<int>.ConvertToGenericList(myList);

which is still rather cumbersome.

I think out first step in fixing this is to convert it from a generaic class, to a generic method:

public class ListToGenericListConverter

{

  public List<T> ConvertToGenericList<T>(IList listOfObjects)

  {

    /// etc.

  }

}

This would make it now:

List<int> yourList = ListToGenericListConverter.ConvertToGenericList<int>(myList);

which doesn't look much different, but, since the class now is not involved with the method, we can add it to some class of utility function, which presumably, a simplier name:

List<int> yourList = Utils.ConvertToGenericList<int>(myList);

Also, "ConvertToGenericList" should be changed.  "List<T>" is a generic list.  For that matter, "ArrayList" is a "generic list". "List<int>" is list of a specific type (which just happened to be created using a generic class), and it's important here because it is a specific list.

Now, let's talk implementation.  I see two problems here --- The three copies (which others have mentioned), and the fact that the use must explicitly state the type of the conversion.   You try at fixing them:

static void Convert<T>(ICollection src, out List<T> dest)

{

dest = new List<T>(src.Count);

foreach(T item in src)

{

dest.Add(item);

}

}

static void Convert<T>(IEnumerable src, out List<T> dest)

{

dest = new List<T>();

foreach(T item in src)

{

dest.Add(item);

}

}

They would be used thusly:

ArrayList al = new ArrayList();

al.Add(2);

al.Add(4);

al.Add(3);

al.Add(1);

List<int> il;

Utils.Convert(al, out il);

Initially, I wasn't sure if I wanted to go with the ICollection version (which is more effiecent) or the IEnumerable version (which is more usable).  Then I realized I didn't have to choose.  The compiler considers them distinct, and will choose whichever one is a better fit.

# re: Generic List Converter Snippet

Thursday, May 10, 2007 4:11 PM by Scott Modesto

I like how you post a useful snippet and James has to get up on his high-horse so he can talk down to you like hes a bearded great white wizard and you're a repulsive slug struggling with a 3rd grade math assigment.

# re: Generic List Converter Snippet

Thursday, May 10, 2007 4:18 PM by Bil Simser

Let the bearded great white wizard speak, if anything it's Billy McCafferty that's the repulsive slug.

# In search for the fastest IList to IList<T> conversion

Sunday, June 17, 2007 7:06 PM by Ramon Smits

I was yet again busy with a generic data layer. I like type safety as it provides compile time safety