C# - 将属性值从一个实例复制到另一个实例,不同的类

Sar*_*els 4 c# mapping reflection properties

我有两个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);
}
Run Code Online (Sandbox Code Playgroud)

最好的方法是什么?我应该维护单独的Defect属性和DefectViewModel属性列表,以便我可以做到viewModelProperty.SetValue(viewModel, defectValue, null)吗?

编辑: 多亏了JordãoDave的答案,我选择了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
            )
        );
}
Run Code Online (Sandbox Code Playgroud)

然后,PropertyInfo我只有以下几行,而不是所有的业务:

var defect = new Defect();
var defectViewModel = new DefectViewModel();
Mapper.Map<Defect, DefectViewModel>(defect, defectViewModel);
Run Code Online (Sandbox Code Playgroud)