Home > other >  Assign List to a generic list
Assign List to a generic list

Time:03-25

How would you assign a list to a generic list since they are not the same type.

If I have a generic list:

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

and I have another list

List<OtherType> otherList = new List<OtherType>();

After I fill otherList with values. What are ways I can assign otherList to the generic list? Preferably without using a foreach.

CodePudding user response:

if they are the same type you can do a basic type conversion

if(typeof(T) == typeof(OtherType))
    myList = otherList as List<T>;

But that would make no sense, so I'd imagine you need some kind of conversion, problem is we need to specify that T is assignable from your base class

public static class StaticFoo
{
    public static List<T> Foo<T>() where T : class
    {
        List<MyOtherClass> returnList = new List<MyOtherClass>() { new MyOtherClass() };
        if(typeof(T).IsAssignableFrom(typeof(MyOtherClass)))
            return returnList.Select(x => x as T).ToList();
        throw new Exception($"Cannot convert {typeof(T)} to MyOtherClass");
    }
}
public class MyClass { }
public class MyOtherClass : MyClass { }

The above code will work if you call it with T = MyClass or any other class that myOtherClass can be cast to. Alternatively you might want a concrete conversion method for a set of predefined types, it's kind of hacky but you could do something like this

public static class StaticFoo
{
    public static List<T> Foo<T>() where T : class
    {
        List<MyOtherClass> returnList = new List<MyOtherClass>() { new MyOtherClass() };
        return returnList.Select(x => x.Convert(typeof(T)) as T).ToList();
    }
}
public class MyOtherClass {
    public object Convert(Type type) {
        if (type == typeof(string)) //more if statements for more types
            return this.ToString(); //just an example
        throw new NotImplementedException($"No cast available for type {type}");
    }

}

Some context for the relationship between the generic type and your concrete class would be helpful

edit: some advice that ignores your actual question. Most likely, you want to create an interface and return a list of that interface (I'm assuming that will match your use case more closely). Alternatively just change the signature to return List< object> - then you can do

return otherList.ToList<object>();

CodePudding user response:

List<T> is invariant, so you can only assign lists of the same type. The closest you can come is creating a new list with the same items.

List<T> list = otherList.Select( x => (T)x ).ToList();
  • Related