c#将GetValue的结果从PropertyInfo转换为一个泛型列表

本文关键字:一个 列表 泛型 转换 GetValue 结果 PropertyInfo | 更新日期: 2023-09-27 18:01:51

我试图构建一个应用程序,其中类的属性是根据一些XML文件中的值设置的。
有些类的属性由它的子类列表组成。由于我制作这个程序的方式,属性必须通过propertyinfo类设置。我的问题是,我有麻烦获取孩子的列表(ICollection in Derived2)。
它必须被强制转换为泛型列表(ICollection OR HashSet),所以我不必在每个派生类中复制粘贴相同的setChild方法。我试过将GetValue返回值转换为ICollectionHashSetIENumerable,没有工作。也许解决方案可以是使用另一个方法的PropertyInfo类?
略为简化的代码示例代码:

public interface Superclass
{}
public class Derived1 : Superclass {}
public class Derived2 : Superclass
{
    public Derived2()
    {
        PatientForloeb = new HashSet<Derived1>();
    }
    public virtual ICollection<Derived1>Derived1{ get; set; }
}
class Program
{
    static void Main(string[] args)
    {
        List<Derived1> children = new List<Derived1>();
        children.Add(new Derived1());
        var parent = new Derived2();
        setChild(parent, children);
    }
    private static void setChild(Superclass parent, List<Derived1> children)
    {
        foreach (var child in children)
        {
            var p = (parent.GetType().GetProperty(child.GetType().Name)); // This is ugly, should be based on type not name, but it works for my app.
            var pi = p.GetValue(parent) as HashSet<Superclass>; ///////////<-------This gives null. This is the problem.
            pi.add(child);
        }
    }
}

c#将GetValue的结果从PropertyInfo转换为一个泛型列表

  1. Superclass没有属性,所以实际上pnull
  2. 您的属性名称是PatientForloeb而不是Derived1,也许您正在寻找这个?

    var p = parent
            .GetType()
            .GetProperties()
            .First(x => x.PropertyType.GetGenericArguments()[0] == children.GetType().GetGenericArguments()[0]); 
    
  3. HashSet<T>ICollection<T>,但ICollection<T>不是HashSet。例如,在这种情况下你会期望发生什么:

    var list = new List<int>();
    var collection = list as ICollection<int>; // okey
    var set = collection as HashSet<int>; // null
    

但这不是唯一的问题,因为ICollection<T>不是协变。此外,您甚至不需要使用as操作符,只需获取值并设置它。

事实上,你甚至不需要得到你的财产的价值。如果你看它仔细,你得到你的parent的属性值,然后试图设置该值回parent .即使这是有效的,没有什么会改变。你需要:

p.SetValue(parent, children);