使用反射和扩展方法在对象之间复制属性

本文关键字:对象 之间 复制 属性 方法 反射 扩展 | 更新日期: 2023-09-27 18:04:43

这是我的代码,我创建一个对象(实体)的"副本"到一个自定义对象。
它只复制源文件和目标文件中同名的属性。

我的问题是当一个实体有一个到另一个实体的导航时,对于这种情况,我添加了一个自定义属性,我在自定义类的属性上面添加了一个自定义属性。

例如,自定义类看起来像:
public class CourseModel:BaseDataItemModel
{
    public int CourseNumber { get; set; }
    public string Name { get; set; }
    LecturerModel lecturer;
    [PropertySubEntity]
    public LecturerModel Lecturer
    {
        get { return lecturer; }
        set { lecturer = value; }
    }
    public CourseModel()
    {
         lecturer = new LecturerModel();
    }
 }

问题是在targetProp.CopyPropertiesFrom(sourceProp);行,当我尝试再次调用扩展方法(复制嵌套对象)时,因为类型是在运行时确定的,扩展方法无法在编译时解决。

也许我错过了什么…

public static void CopyPropertiesFrom(this BaseDataItemModel targetObject, object source)
{
   PropertyInfo[] allProporties = source.GetType().GetProperties();
   PropertyInfo targetProperty;
   foreach (PropertyInfo fromProp in allProporties)
   {
      targetProperty = targetObject.GetType().GetProperty(fromProp.Name);
      if (targetProperty == null) continue;
      if (!targetProperty.CanWrite) continue;
     //check if property in target class marked with SkipProperty Attribute
     if (targetProperty.GetCustomAttributes(typeof(SkipPropertyAttribute), true).Length != 0) continue;
     if (targetProperty.GetCustomAttributes(typeof(PropertySubEntity), true).Length != 0)
     {
        //Type pType = targetProperty.PropertyType;
        var targetProp = targetProperty.GetValue(targetObject, null);
        var sourceProp = fromProp.GetValue(source, null);
        targetProp.CopyPropertiesFrom(sourceProp); // <== PROBLEM HERE
        //targetProperty.SetValue(targetObject, sourceEntity, null);
     }
       else
           targetProperty.SetValue(targetObject, fromProp.GetValue(source, null), null);
   }
}

使用反射和扩展方法在对象之间复制属性

你必须先转换。

((BaseDataItemModel)targetProp).CopyPropertiesFrom(sourceProp); 

您要么需要将targetProperty转换为BaseDataItemModel,这样您就可以在其上调用扩展方法(edit:如代理j的回答),否则您可以忘记该基类。为什么你的反射算法需要它?它可以在任何类上工作,并且完全由属性上的属性来指导。

如果它在任何object上工作,它不应该是一个扩展方法