Best way to convert a non-generic collection to generic collection
Asked Answered
S

2

16

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!

Stinko answered 8/4, 2009 at 21:4 Comment(0)
S
28

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();
}
Stride answered 8/4, 2009 at 21:15 Comment(2)
I don't think you need the Cast<T>() after the OfType<T>(), but I could be mistaken.Mantis
@Mantis - You're right. OfType<T>() will return IEnumerable<T>, so that's all you'd need. Edited and fixed.Stride
G
10

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.

Generalissimo answered 18/8, 2009 at 6:43 Comment(1)
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.Fantasia

© 2022 - 2024 — McMap. All rights reserved.