我正在尝试构建一个应用程序,其中基于som XML文件中的值设置类的属性
有些类具有包含其子项列表的属性。由于我制作这个程序的方式,必须通过propertyinfo类设置属性。我的问题是我在获取子列表时遇到问题( Derived2 中的ICollection)。
它必须强制转换为通用列表( 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);
}
}
}
答案 0 :(得分:1)
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);