通过c#</someinnerclass>中的反射访问内部类型的ICollection <someinnerclass>

时间:2011-10-28 19:02:39

标签: c# .net reflection

我正在尝试使用反射在对象上设置属性。 该属性是一个ICollection - 如果Collection尚未实例化,我想完成它。我的问题是我在获取ICollection的内部类型时遇到问题

这是我的班级

public class Report(){
    public virtual ICollection<Officer> OfficerCollection { get; set; }
}

我正试图通过反思

访问下面定义的'官员'类
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?
}

3 个答案:

答案 0 :(得分:3)

给它一个旋转:

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

答案 1 :(得分:2)

首先,您必须获得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; }
    }
}

答案 2 :(得分:0)

忽略整个设计听起来很糟糕的问题,我会尽力回答你的问题。您可以使用Type type = ...GetProperty(...).PropertyType找到属性的类型。如果类型是具体类型 - 而不是当前的接口 - 那么您可以使用System.Activator.CreateInstance(type, null) - 其中null表示没有构造函数参数 - 创建此具体类型的实例。鉴于您的属性类型实际上是一个接口,您不知道是应该创建列表,数组,集合还是满足此类型的任何其他类型。然后,您需要使用SetValue将实例分配给属性,但当然我们无法做到这一点。

您应该使用此信息重新评估您的设计,使其不依赖于反射,而是使用通用参数化(查看new()约束)和属性的延迟初始化(如果您认为有意义 - 我们是不介意读者。)