Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically adding items to a List<T> through reflection

Lets say I have this class

class Child {
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

class Container {
    public List<Child> { get; set; }
}

I'm working on a deserializer of sorts and I want to be able to create and populate the Child list from the data retrieved. I've gotten this far (I've cut out a lot of handling for other types for this example so its unnecessarily "iffy" but bear with me):

var props = typeof(Container).GetProperties();

foreach (var prop in props) {
    var type = prop.PropertyType;
    var name = prop.Name;

    if (type.IsGenericType) {
        var t = type.GetGenericArguments()[0];

        if (type == typeof(List<>)) {
            var list = Activator.CreateInstance(type);
            var elements = GetElements();

            foreach (var element in elements) {
                var item = Activator.CreateInstance(t);
                Map(item, element); 

                // ??? how do I do list.Add(item) here?
            }

            prop.SetValue(x, list, null); // x is an instance of Container

        }
    }
}

I can't figure out how to cast list to essentially List<t.GetType()> so I can access the add method and add the item.

like image 652
John Sheehan Avatar asked Oct 10 '09 03:10

John Sheehan


2 Answers

I would say you should cast down to System.Collections.IList and directly call the Add method. Pros: simple, no ugly reflection. Cons: causes boxing for Lists containing value types.

like image 80
bobbymcr Avatar answered Oct 04 '22 01:10

bobbymcr


This should work unless I am really missing something.

Outside of the loop

var add = type.GetMethod("Add");

Inside the loop

add.Invoke(list, new[] { item });
like image 28
ChaosPandion Avatar answered Oct 04 '22 01:10

ChaosPandion