Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cast a List of object without using LINQ

Tags:

c#

.net

.net-2.0

From my question at here: Cast in List object

I accepted the answer using LINQ:

myA = myB.Cast<A>().ToList();

I have a question: we have any other solutions without using LINQ, because my application is using .NET Framework 2.0.

UPDATE: If I have several classes myB, myC, myD, myE, ... which derived from myA, I need a function which can convert a list to list (T maybe myB or myC or myD, ...) to avoid repeat same codes. The function input is a list<T> and the function output is a list<myA>.

Thanks.

like image 311
Leo Vo Avatar asked Dec 09 '25 23:12

Leo Vo


2 Answers

A simple foreach will do the trick (for readability, i've named the classes Foo and Bar)

myFoos = new List<Foo>();
foreach (Bar bar in myBars)
{
  myFoos.Add((Foo)bar);
}

After question edit:

To convert a list of multiple child classes into a base class, I would create a class called BaseCollection, than would inherit from List, as usually some other operations are required of the lists as well. Some usefull methods might be:

 public class BaseCollection : List<Base>
 {
    public static BaseCollection ToBase<T>(IEnumerable<T> source) where T: Base
    {
       BaseCollection result = new BaseCollection();
       foreach (T item in source)
       {
          result.Add(item);
       }
       return result;
     }

    public static List<T> FromBase<T>(IEnumerable<Base> source) where T: Base
    {
       List<T> result = new List<T>();
       foreach (Base item in source)
       {
          result.Add((T)item);
       }
       return result;
     }


    public static List<T> ChangeType<T, U>(List<U> source) where T: Base where U:Base
    {        
        List<T> result = new List<T>();        
        foreach (U item in source)        
        {           
            //some error checking implied here
            result.Add((T)(Base) item);        
        }        
        return result;      
    }  

    ....
    // some default printing
    public void Print(){...}         
    ....
    // type aware printing
    public static void Print<T>(IEnumerable<T> source) where T:Base {....}
    ....
 }

That would enable me to easily cast any descendant to and from base class collections, and use them like this:

List<Child> children = new List<Child>();
children.Add(new Child { ID = 1, Name = "Tom" });
children.Add(new Child { ID = 2, Name = "Dick" });
children.Add(new Child { ID = 3, Name = "Harry" });

BaseCollection bases = BaseCollection.ToBase(children);
bases.Print();

List<Child> children2 = BaseCollection.FromBase<Child>(bases);
BaseCollection.Print(children2);
like image 196
SWeko Avatar answered Dec 11 '25 11:12

SWeko


For .NET 2.0 you could write your own Cast method, using the Linq code as a guideline:

public static class EnumerableHelper
{
    public static IEnumerable<TResult> Cast<TResult>(IEnumerable source)
    {
        IEnumerable<TResult> enumerable = source as IEnumerable<TResult>;
        if (enumerable != null) return enumerable;
        if (source == null) throw new ArgumentNullException("source");        
        foreach(object element in source)
        {
            yield return (TResult) element;
        }
    }
}

then use it as follows:

myA = new List<A>(EnumerableHelper.Cast<A>(myB));   
like image 34
Joe Avatar answered Dec 11 '25 13:12

Joe