【发布时间】:2011-04-06 08:52:32
【问题描述】:
我有两个 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's 和Dave's 的回答,我选择了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);
【问题讨论】:
标签: c# reflection properties mapping