我有两个C#类,它们拥有许多相同的属性(按名称和类型)。我想要能够将
然后,不用所有那些关于
Defect
实例中的所有非空值复制到DefectViewModel
实例中。我希望使用反射来完成这个操作,使用GetType().GetProperties()
。我尝试了以下代码:var defect = new Defect();
var defectViewModel = new DefectViewModel();
PropertyInfo[] defectProperties = defect.GetType().GetProperties();
IEnumerable<string> viewModelPropertyNames =
defectViewModel.GetType().GetProperties().Select(property => property.Name);
IEnumerable<PropertyInfo> propertiesToCopy =
defectProperties.Where(defectProperty =>
viewModelPropertyNames.Contains(defectProperty.Name)
);
foreach (PropertyInfo defectProperty in propertiesToCopy)
{
var defectValue = defectProperty.GetValue(defect, null) as string;
if (null == defectValue)
{
continue;
}
// "System.Reflection.TargetException: Object does not match target type":
defectProperty.SetValue(viewModel, defectValue, null);
}
如何做到最好呢?我应该维护Defect
属性和DefectViewModel
属性的单独列表,以便我可以执行viewModelProperty.SetValue(viewModel, defectValue, null)
吗?
编辑:感谢Jordão和Dave的回答,我选择了AutoMapper。DefectViewModel
在WPF应用程序中,因此我添加了以下App
构造函数:
public App()
{
Mapper.CreateMap<Defect, DefectViewModel>()
.ForMember("PropertyOnlyInViewModel", options => options.Ignore())
.ForMember("AnotherPropertyOnlyInViewModel", options => options.Ignore())
.ForAllMembers(memberConfigExpr =>
memberConfigExpr.Condition(resContext =>
resContext.SourceType.Equals(typeof(string)) &&
!resContext.IsSourceValueNull
)
);
}
然后,不用所有那些关于
PropertyInfo
的事情,我只需要以下这行代码:var defect = new Defect();
var defectViewModel = new DefectViewModel();
Mapper.Map<Defect, DefectViewModel>(defect, defectViewModel);