Cast Object to Generic List

83,660

Solution 1

What a sticky problem. Try this:

List<Contact> c = null;
List<Address> a = null;
List<Document> d = null;

object o = GetObject();

c = o as List<Contact>;
a = o as List<Address>;
d = o as List<Document>;

Between c, a, and d, there's 2 nulls and 1 non-null, or 3 nulls.


Take 2:

object o = GetObject();
IEnumerable e = o as IEnumerable;
IEnumerable<Contact> c = e.OfType<Contact>();
IEnumerable<Address> a = e.OfType<Address>();
IEnumerable<Document> d = e.OfType<Document>();

Solution 2

Lots of trial and error gave me this on SL 5 but it should also work on a regular C#. You also need to add LINQ to your using list for the last half to work.

    List<object> myAnythingList = (value as IEnumerable<object>).Cast<object>().ToList()

Enjoy!

Solution 3

I had the same problem and solved it by looking at the purpose of the casted objects. Do you really need to cast it to the specific (closed) generic types? In my case the (open) generic type had an interface which I used to cast it to.

var list = obj as IUsefulInterface;

list.MethodThatIAmInterestedIn();

Solution 4

I had this problem when writing a Validation Attribute where I received an object from the ValidationContext and knew that it needed to be a list, but not what it was a list of. It threw an exception when I tried to cast it as IEnumerable<object> but it could be cast as IEnumerable which then allowed the .Cast<object>() via linq.

In the end what worked was:

var enumerable = listObject as IEnumerable;
var list = enumerable.Cast<object>().ToList();

Solution 5

A general solution like this (to instantiate a type with a generic parameter based on a System.Type object) is not possible. If you're really just dealing with these three types, though, then you're in luck because it's pretty easy:

Type t = typeof(obj);

if (t == typeof(List<Contact>)) {
    var contactList = (List<Contact>)obj;
    // do stuff with contactList

} else if (t == typeof(List<Address>)) {
    var addressList = (List<Address>)obj;
    // do stuff with addressList

} else if (t == typeof(List<Document>)) {
    var documentList = (List<Document>)obj;
    // do stuff with documentList
}
Share:
83,660
JoeLoco
Author by

JoeLoco

Updated on July 23, 2022

Comments

  • JoeLoco
    JoeLoco almost 2 years

    I have 3 generict type list.

    List<Contact> = new List<Contact>();
    List<Address> = new List<Address>();
    List<Document> = new List<Document>();
    

    And save it on a variable with type object. Now i nedd do Cast Back to List to perfom a foreach, some like this:

    List<Contact> = (List<Contact>)obj;
    

    But obj content change every time, and i have some like this:

    List<???> = (List<???>)obj;
    

    I have another variable holding current obj Type:

    Type t = typeof(obj);
    

    Can i do some thing like that??:

    List<t> = (List<t>)obj;
    

    Obs: I no the current type in the list but i need to cast , and i dont now another form instead:

    List<Contact> = new List<Contact>();
    
  • jgerman
    jgerman about 10 years
    This is the ONLY solution I've found across Stack Overflow in the last hour that's worked. THANKS! My problem was that in reflection .Invoke() returns and object, which at runtime is a List<Some_Class_that_implements_IUnifyingDef>. But I don't know the class, only the interface IUnifyingDef. Both direct casting and using Convert() threw exceptions or would fail to compile.
  • JobaDiniz
    JobaDiniz over 7 years
    the problem with that approach is that ToList() create another list and it is not the original instance
  • Bill Noel
    Bill Noel over 6 years
    I would have never found this on my own. Thank you so much.