Best way to convert a non-generic collection to generic collection

10,139

Solution 1

Since you can guarantee they're all TestClass instances, use the LINQ Cast<T> method:

public static List<TestClass> ConvertToGenericClass(NonGenericCollection collection)
{
   return collection.Cast<TestClass>().ToList();
}

Edit: And if you just wanted the TestClass instances of a (possibly) heterogeneous collection, filter it with OfType<T>:

public static List<TestClass> ConvertToGenericClass(NonGenericCollection collection)
{
   return collection.OfType<TestClass>().ToList();
}

Solution 2

Another elegant way is to create a wrapper class like this (I include this in my utilities project).

public class EnumerableGenericizer<T> : IEnumerable<T>
{
    public IEnumerable Target { get; set; }

    public EnumerableGenericizer(IEnumerable target)
    {
        Target = target;
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    public IEnumerator<T> GetEnumerator()
    {
        foreach(T item in Target)
        {
            yield return item;
        }
    }
}

You can now do this:

IEnumerable<MyClass> genericized = 
    new EnumerableGenericizer<MyClass>(nonGenericCollection);

You could then wrap a normal generic list around the genericized collection.

Share:
10,139
J.W.
Author by

J.W.

Language: Java/ C++ / C#

Updated on June 18, 2022

Comments

  • J.W.
    J.W. about 2 years

    What is the best way to convert a non-generic collection to a generic collection? Is there a way to LINQ it?

    I have the following code.

    public class NonGenericCollection:CollectionBase
    {
        public void Add(TestClass a)
        {
            List.Add(a);
        }
    }
    
    public class ConvertTest
    {
        public static List<TestClass> ConvertToGenericClass( NonGenericCollection    collection)
        {
            // Ask for help here.
        }
    }
    

    Thanks!

  • Samuel
    Samuel about 15 years
    I don't think you need the Cast<T>() after the OfType<T>(), but I could be mistaken.
  • Mark Brackett
    Mark Brackett about 15 years
    @Samuel - You're right. OfType<T>() will return IEnumerable<T>, so that's all you'd need. Edited and fixed.
  • Stéphane Gourichon
    Stéphane Gourichon almost 10 years
    This solution is more complicated but it's useful to solve a stronger problem than the question and other answer. When for some reason the original collection is known and modified by some other objects and you want to instantiate only one genericized collection hat will reflect future changes. Beware, though. It loses some of the more high level interfaces that may be needed for efficient processing, for example IList<T>. In other words, if performance is important (in LINQ queries for example) it will have to be completed with those higher level interfaces.