2016-08-26 6 views
3

У меня есть структура класса ниже. Я получаю эту ошибку. Я что-то пропустил?Как добавить объект в свойство общего списка экземпляра класса с использованием отражения

Объект не соответствует типу цели.

Структура класса

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; } 
} 

Что я пытаюсь:

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 }); 
+0

При попытке воспроизвести проблему, я нашел еще одну проблему. Вы устанавливаете 'Credit to' 1', в то время как это строка. Измените его тип на int. –

+0

@stuartd есть причина, по которой я использую отражение справа? – Helio

+0

Когда я попробовал вашу часть кода, после этого утверждения я получил нулевое значение. Тип t = Тип.GetType («Лекция»); Таким образом, очевидно, что следующий оператор будет вызывать исключение null ref, но сообщение о том, что вы получили, отличается от него. Я мог видеть, что использование Type.GetType может быть проблемой (если в случае), то ознакомьтесь с нижеприведенным ответом от Jon Skeet - http://stackoverflow.com/a/1044472/1966993 –

ответ

1

Это должно быть что-то вроде этого:

// 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. Вот скрипка link.

+0

Спасибо за ответ, .GetValue (s), что мне не хватает ... – Helio

+0

Вам также не нужно 'Type.GetType' - просто используйте' PropertyInfo.PropertyType'. – Dennis

1

Проблема заключается в том, что вы получаете метод AddList<Lecture> и пытаетесь вызвать его с помощью PropertyInfo в качестве экземпляра, вызывающего метод.

Изменение:

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

к:

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

Таким образом pi.GetValue(s) Получает List<Lecture> сам из PropertyInfo (который представляет только само имущество, а также его get и set методами, и вызывать его Add с использованием object[] в качестве аргументов.


Еще одна вещь. почему использование:

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

Когда вы можете просто использовать:

Type ti = pi.PropertyType;