4

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 });
Tamir Vered
  • 10,187
  • 5
  • 45
  • 57
Helio
  • 621
  • 1
  • 4
  • 24
  • While trying to reproduce the problem, I have found another problem. You set `Credit to `1` while it is a string. Change its type to int. – Yeldar Kurmangaliyev Aug 26 '16 at 08:38
  • @stuartd there is a reason i use reflection right? – Helio Aug 26 '16 at 08:42
  • When I tried your piece of code, I got an null value after this statement Type t = Type.GetType("Lecture"); So obviously the next statement will throw an null ref exception, but the message what you got is different one's. I could see the usage of Type.GetType might be the issue (if in case), then check out this below answer from Jon Skeet - http://stackoverflow.com/a/1044472/1966993 – G K Aug 26 '16 at 08:46
  • @Ganesh you should specify the namespace of Lecture class. – Helio Aug 26 '16 at 08:49
  • Hmm, I tried even with that also. But still I am getting null reference exception. Here is the code which I have changed it, Schedule s = new Schedule(); Type t = Type.GetType("SO._39161851.Lecture, SO._39161851"); object obj = Activator.CreateInstance(t); – G K Aug 26 '16 at 08:53
  • I got it, now it's working for me. – G K Aug 26 '16 at 09:37

2 Answers2

2

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.

Dennis
  • 37,026
  • 10
  • 82
  • 150
2

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;
Tamir Vered
  • 10,187
  • 5
  • 45
  • 57