JoeLoco
JoeLoco

Reputation: 2214

Cast Object to Generic List

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>();

Upvotes: 19

Views: 98030

Answers (10)

Vaibhav Pathade
Vaibhav Pathade

Reputation: 131

List contactList = myObject as List;

List addressList = myObject as List;

List documentList = myObject as List;

Upvotes: 0

Harsha
Harsha

Reputation: 1

Employee employee=new Employee();
List<Employee> emplist=new();
emplist.Add(employee);

This is correct way Thank you

Upvotes: -2

Vadim
Vadim

Reputation: 414

I ran into same problem - I have a collection which data type is only known at run time and I can't cast it to anything. None of the solutions above worked. Finally I solved it by serializing to JSON and de-serializing back. Of course it's not ideal, but may help someone.

string jsonString = JsonConvert.SerializeObject(myObject);
jsonString = "{ values:" + jsonString + "}";

JObject j = JObject.Parse(jsonString);

//now we can iterate over the list
foreach (var x in j["values"])
{
    string name = x.ToString();
    ...
}

Upvotes: 1

ste-fu
ste-fu

Reputation: 7497

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();

Upvotes: 5

Vincent65535
Vincent65535

Reputation: 129

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();

Upvotes: 3

Andrew Marais
Andrew Marais

Reputation: 965

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!

Upvotes: 46

dominic
dominic

Reputation: 1

You might need to do:

if(object is List)
{
    list = (List)object
}

Upvotes: -1

Amy B
Amy B

Reputation: 110221

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>();

Upvotes: 36

Femaref
Femaref

Reputation: 61497

No, you can't cast without going around corners (this is: reflection), generic type parameters have to be known at compile time. You can of course do something like this:

content.Where(o => o is type).ToList().Foreach(stuff);

Upvotes: 0

Dan Tao
Dan Tao

Reputation: 128437

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
}

Upvotes: 2

Related Questions