为了一个关于ObservableCollection的问题,我最近写了一个通用的扩展方法,它应该从另一个对象中加载一个对象,即将源的所有属性分配给目标,并且如果属性是引用类型,则递归地执行此操作。我使用反射做得很好,但在涉及引用类型的属性类型时遇到了问题,这是我的第一种方法:
这里的问题在于
我想到了一种解决方法,需要显式传递类型,但这是非常冗余的,理论上应该可以不需要。
我也尝试使用
public static void Load<T>(this T target, T source, bool deep)
{
foreach (PropertyInfo property in typeof(T).GetProperties())
{
if (property.CanWrite && property.CanRead)
{
if (!deep || property.PropertyType.IsPrimitive || property.PropertyType == typeof(String))
{
property.SetValue(target, property.GetValue(source, null), null);
}
else
{
property.GetValue(target, null).Load(property.GetValue(source, null), deep);
}
}
}
}
这里的问题在于
PropertyInfo.GetValue
返回一个对象,接下来递归调用中T
将等于object
,因此我无法获取对象实际拥有的属性。我想到了一种解决方法,需要显式传递类型,但这是非常冗余的,理论上应该可以不需要。
public static void Load<T>(this T target, Type type, T source, bool deep)
{
foreach (PropertyInfo property in type.GetProperties())
{
if (property.CanWrite && property.CanRead)
{
if (!deep || property.PropertyType.IsPrimitive || property.PropertyType == typeof(String))
{
property.SetValue(target, property.GetValue(source, null), null);
}
else
{
object targetPropertyReference = property.GetValue(target, null);
targetPropertyReference.Load(targetPropertyReference.GetType(), property.GetValue(source, null), deep);
}
}
}
}
我也尝试使用
dynamic targetPropertyReference
,但是我得到了一个运行时异常,说找不到Load
方法,这真让人恼火。除此之外,Convert.ChangeType
也很方便地返回一个object
,我似乎无法将对象转换为它本来的类型。当然,我在网上寻找答案,但迄今为止没有成功。
target.GetType()
了,非常感谢!我想这样就可以了(我的意思是,如果某个东西被装箱了,那么它被装箱只是为了更改所有超类型特定属性的概率有多大,然后再取消装箱)。我不会将其标记为答案,因为它并没有回答实际问题(或者说它回答了吗?),但如果在一个月内没有答案出现,我会改变问题本身。 - H.B.T
应该是什么,创建一个带有该类型参数的方法版本,然后调用它。 - Ani