[英]Accessing inner type of ICollection<SomeInnerClass> through reflection in c#
我正在尝试使用反射在对象上设置属性。 该属性是一个ICollection-如果尚未实例化Collection,我想完成它。 我的问题是我在获取ICollection的内部类型时遇到问题
这是我的课
public class Report(){
public virtual ICollection<Officer> OfficerCollection { get; set; }
}
我正在尝试通过反射访问下面定义的“ Officer”类
public class Officer(){
public string Name{ get; set; }
}
程式码片段
Report report = new Report()
PropertyInfo propertyInfo = report.GetType().GetProperty("OfficerCollection");
object entity = propertyInfo.GetValue(report, null);
if (entity == null)
{
//How do I go about creating a new List<Officer> here?
}
旋转一下:
Report report = new Report();
PropertyInfo propertyInfo = report.GetType().GetProperty("Officer");
object entity = propertyInfo.GetValue(report, null);
if (entity == null)
{
Type type = propertyInfo.PropertyType.GetGenericArguments()[0];
Type listType = typeof(List<>).MakeGenericType(type);
var instance = Activator.CreateInstance(listType);
propertyInfo.SetValue(...);
}
首先,您必须获得Officer
属性:
var propertyType = propertyInfo.PropertyType;
然后您提取通用类型参数:
var genericType = propertyType.GetGenericArguments()[0];
在调用之后,创建一个通用列表:
var listType = typeof(List<>).MakeGenericType(genericType);
最后创建一个通用列表的新实例:
var listInstance = Activator.CreateInstance(listType);
玩得开心 ;)
编辑:
有时带反射演奏很不错,但我建议您这样做:
public class Report()
{
private ICollection<Officer> officers;
public virtual ICollection<Officer> Officer
{
get
{
if(officers == null)
officers = new List<Officer>();
return officers;
}
set { officers = value; }
}
}
忽略整个设计听起来很糟糕的问题,我将尽力回答您的问题。 您可以使用Type type = ...GetProperty(...).PropertyType
查找属性的Type type = ...GetProperty(...).PropertyType
。 如果类型是具体类型(而不是当前的接口),则可以使用System.Activator.CreateInstance(type, null)
-其中null
表示没有构造函数参数-创建此具体类型的实例。 鉴于您的属性类型实际上是一个接口,因此您不知道是否应该创建列表,数组,集合或满足该类型的任何其他类型。 然后,您将需要使用SetValue将实例分配给该属性,但是当然我们无法做到这一点。
您应该利用此信息重新评估您的设计,使其不依赖于反射,而应使用通用参数化(请参阅new()
约束)和属性的惰性初始化(如果您认为有道理-我们不介意读者。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.