【发布时间】:2018-12-28 21:45:00
【问题描述】:
我需要将属性的值从一个类复制到另一个是相同基类型的后代。源对象和目标对象可能位于同一继承分支的不同级别,即一个继承自另一个,或者是不同分支的后代,即它们共享一个共同的基类型。
A
B1 B2
C1 C2 C3
从上面的结构中,我可能想将所有属性从 A 复制到 C1、C2 到 C3、C3 到 B1 等。基本上任何可能的组合都来自树。显然,我只能复制源类型中存在的属性,这些属性也必须存在于目标类型中。
迭代源类型的属性很简单
var sourceProperties = source.GetType().GetProperties();
但是如何检查目标类型上声明的属性?仅按名称检查是不够的,因为它们可能具有不同的类型。同样在过去,我使用new 对重复属性产生了不好的体验。
不幸的是,C# 或 .NET 没有内置方法来检查类型是否具有特定的 PropertyInfo,例如 Type.HasProperty(PropertyInfo)。我能想到的最好办法是检查属性是否由共享基类型声明。
public static void CopyProperties(object source, object target)
{
var targetType = target.GetType();
var sharedProperties =source.GetType().GetProperties()
.Where(p => p.DeclaringType.IsAssignableFrom(targetType));
foreach (var property in sharedProperties)
{
var value = property.GetValue(source);
if (property.CanWrite)
property.SetValue(target, value);
}
}
问题:有更好的解决方案吗?
【问题讨论】:
-
您尝试过使用 AutoMapper 吗?您可以将其配置为将一种类型的所有同名属性复制到另一种类型,而无需自己实现。
-
我知道 AutoMapper,但只为这个用例添加依赖项似乎有点过头了。它不是单个应用程序,而是框架的一部分,因此添加依赖项需要更加谨慎。
-
@Toxantron 这可能不是矫枉过正,如果您必须动态执行此操作,如果您知道模型及其仅适用于少数或基本类型,您可以创建手动适配器,但如果它频繁或动态只用automapper,用反射写一个工具会比automapper慢。
-
只是在 automapper 上加入 +1。它非常轻巧,被广泛使用和喜爱。
标签: c# optimization reflection