Better way to convert IEnumerable<T> to user type

.net, c#, linq

Solution

Your method `MakeRigCollection` is basically the right way to do it. Here is a variant that is slightly more verbose to use but much simpler to implement:

TCollection MakeRigCollectionSimple<TCollection, TItem>(
    this IEnumerable<TItem> items, TCollection collection)
    where TCollection : ICollection<TItem>
{
        foreach (var myObj in items)
            collection.Add(myObj);
        return collection;
}

I hope I got it right. You use it like this:

MakeRigCollectionSimple(items, new MyCollection());

or

items.MakeRigCollectionSimple(new MyCollection());

Now you have the 2nd argument to fill out, but in exchange we were able to get rid of all the crazy generics stuff. Just simple generics left. And type inference kicks in fully. Also, this will work for all collection types, not just your RigCollections.

Problem

I have a custom collection type, defined as such: ``` public abstract class RigCollectionBase<T> : Collection<T>, IEnumerable<T>, INotifyPropertyChanged, IBindingList, ICancelAddNew where T : BusinessObjectBase, new() ``` Note: this is the base class, there are 20 or so child classes that are implemented like so: ``` public class MyCollection : RigCollectionBase<MyObject> ``` We use a lot of Linq in our code, and as you probably know, Linq functions return `IEnumerable<T>`. What I'm looking for, is an easy and simple way to go back to `MyCollection` from `IEumberable<MyObject>`. Casting is not allowed, I get the exception "Cannot cast from ..." Here is the answer I came up with, and it does work, but it seems kind of clunky and...overcomplicated. Maybe its not, but I figured I would get this out there to see if there's a better way. ``` public static class Extension { /// <summary> /// Turn your IEnumerable into a RigCollection /// </summary> /// <typeparam name="T">The Collection type</typeparam> /// <typeparam name="U">The Type of the object in the collection</typeparam> /// <param name="col"></param> /// <returns></returns> public static T MakeRigCollection<T, U> (this IEnumerable<U> col) where T : RigCollectionBase<U>, new() where U : BusinessObjectBase, new() { T retCol = new T(); foreach (U myObj in col) retCol.Add(myObj); return retCol; } } ``` What I'm really looking for, I guess, is this. Is there a way to implement the base class so that I can use a simple cast to go from IEnumerable into MyCollection... ``` var LinqResult = oldCol.Where(a=> someCondition); MyCollection newCol = (MyCollection)LinqResult; ``` No, the above code doesn't work, and I'm actually not 100% certain why that is...but it doesn't. It just feels like there is some very obvious step that I'm not seeing....

Original source