我有兩個C#類,它們具有許多相同的屬性(按名稱和類型)。我希望能夠將Defect
實例中的所有非空值複製到DefectViewModel
的實例中。我希望用反射來做,使用GetType().GetProperties()
。我試過以下內容:C# - 將屬性值從一個實例複製到另一個實例,不同的類
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);
我想過。 'Defect'在外部庫中定義,我寧願不必修改它,因爲爲這些特定的共享屬性添加一個接口在DefectViewModel所在的庫的上下文中確實是有意義的。 – 2010-08-31 16:09:11
這是有道理的。聽起來像你陷入了基於反思的解決方案之一。不過,我建議Henk關於使用構造函數的建議。 – 2010-08-31 18:06:42