У меня есть два класса 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)
?
Изменить: благодаря обоим Жордана и Дэйв, я выбрал 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);