【问题标题】:How to add an object to a generic list property of an instance of a class using reflection如何使用反射将对象添加到类实例的通用列表属性
【发布时间】:2016-08-26 08:32:42
【问题描述】:

我在下面有一个类结构。我收到此错误。我在这里错过了什么吗?

对象与目标类型不匹配。

类结构

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

【问题讨论】:

  • 在尝试重现问题时,我发现了另一个问题。你设置了Credit to 1`,而它是一个字符串。将其类型更改为 int。
  • @stuartd 我使用反射是有原因的吗?
  • 当我尝试你的一段代码时,在这条语句之后我得到了一个空值 Type t = Type.GetType("Lecture");所以很明显下一条语句会抛出一个空引用异常,但是你得到的消息是不同的。我可以看到 Type.GetType 的使用可能是问题(如果以防万一),然后查看 Jon Skeet 的以下答案 - stackoverflow.com/a/1044472/1966993
  • @Ganesh 你应该指定 Lecture 类的命名空间。
  • 嗯,我也试过了。但我仍然收到空引用异常。这是我更改的代码,Schedule s = new Schedule();类型 t = Type.GetType("SO._39161851.Lecture, SO._39161851");对象 obj = Activator.CreateInstance(t);

标签: c# .net reflection generic-list mscorlib


【解决方案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

【讨论】:

  • 你也不需要Type.GetType - 只需使用PropertyInfo.PropertyType
【解决方案2】:

问题是你得到了List&lt;Lecture&gt;Add 方法并尝试使用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)PropertyInfo 中获取List&lt;Lecture&gt; 本身(它只代表属性本身及其getset 方法,并使用您的object[] 调用其Add 方法作为论据。


还有一件事。为什么使用:

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

当你可以使用时:

Type ti = pi.PropertyType;

【讨论】:

    猜你喜欢
    • 2021-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-07
    • 2011-03-05
    • 1970-01-01
    • 2020-08-05
    • 1970-01-01
    相关资源
    最近更新 更多