Helio
Helio

Reputation: 613

How to add an object to a generic list property of an instance of a class using reflection

I have a class structure below. I am getting this error. Am i missing something here?

Object does not match target type.

Class Structure

public class Schedule
{
    public Schedule() { Name = ""; StartDate = DateTime.MinValue; LectureList = new List<Lecture>(); }
    public string Name { get; set; }
    public DateTime StartDate { get; set; }
    public List<Lecture> LectureList { get; set; }
}

public class Lecture
{
    public string Name { get; set; }
    public int Credit { get; set; }
}

What i am trying:

Schedule s = new Schedule();
Type t = Type.GetType("Lecture");
object obj = Activator.CreateInstance(t);
obj.GetType().GetProperty("Name").SetValue(obj, "Math");
obj.GetType().GetProperty("Credit").SetValue(obj, 1);
PropertyInfo pi = s.GetType().GetProperty("LectureList");
Type ti = Type.GetType(pi.PropertyType.AssemblyQualifiedName);
ti.GetMethod("Add").Invoke(pi, new object[] { obj });

Upvotes: 4

Views: 1473

Answers (2)

Tamir Vered
Tamir Vered

Reputation: 10287

The problem is that you get the Add method of List<Lecture> and try to invoke it with PropertyInfo as the instance invoking the method.

Change:

ti.GetMethod("Add").Invoke(pi, new object[] { obj });

to:

object list = pi.GetValue(s);
ti.GetMethod("Add").Invoke(list, new object[] { obj });

That way pi.GetValue(s) gets the List<Lecture> itself from the PropertyInfo (which only represents the property itself along with its get and set methods, and invoke its Add method with your object[] as arguments.


One more thing. why using:

Type ti = Type.GetType(pi.PropertyType.AssemblyQualifiedName);

When you can just use:

Type ti = pi.PropertyType;

Upvotes: 2

Dennis
Dennis

Reputation: 37770

It should be something like this:

// gets metadata of List<Lecture>.Add method
var addMethod = pi.PropertyType.GetMethod("Add");

// retrieves current LectureList value to call Add method
var lectureList = pi.GetValue(s);

// calls s.LectureList.Add(obj);
addMethod.Invoke(lectureList, new object[] { obj });

UPD. Here's the fiddle link.

Upvotes: 2

Related Questions