我试图构建一个应用程序,其中类的属性是根据一些XML文件中的值设置的。
有些类的属性由它的子类列表组成。由于我制作这个程序的方式,属性必须通过propertyinfo类设置。我的问题是,我有麻烦获取孩子的列表(ICollection in Derived2)。
它必须被强制转换为泛型列表(ICollection OR HashSet),所以我不必在每个派生类中复制粘贴相同的setChild方法。我试过将GetValue返回值转换为ICollection, HashSet或IENumerable,没有工作。也许解决方案可以是使用另一个方法的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);
}
}
}
-
Superclass
没有属性,所以实际上p
是null。 -
您的属性名称是
PatientForloeb
而不是Derived1
,也许您正在寻找这个?var p = parent .GetType() .GetProperties() .First(x => x.PropertyType.GetGenericArguments()[0] == children.GetType().GetGenericArguments()[0]);
-
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);