深度克隆时更新基类属性

时间:2016-03-30 14:54:41

标签: c# .net asp.net-mvc-4 deep-copy system.reflection

我有以下基类

public class BaseEntity
{
   public Guid Id{get; set;}
   public string Name{get; set;}
}

我有从这个Base类继承的子类的数量。例如:

public Class Employee : BaseEntity
{
   public string UserId {get; set;} 
   public Role EmpRole {get; set;}
   public IList<Department> EmpDepartment {get; set;}
}

public class Role : BaseEntity
{
   public string Description{get; set;}
}

public Class Department : BaseEntity
{
   Public int NumOfEmployees {get; set;}
}

现在我需要创建一个employee对象的深层副本,并且必须更新从BaseEntity Class继承的所有属性的Id字段。

我正在使用以下代码来实现它,但它不起作用:

public static T DeepClone<T>(T obj)
{
    IFormatter formatter = new BinaryFormatter();
    Stream stream = new MemoryStream();
    using (stream)
    {
        formatter.Serialize(stream, obj);
        stream.seek(0, SeekOrigin.Begin);
        var newObj = (T)formatter.Deserialize(stream);
        return updateClone(newObj);
    }
}

public static T UpdateClone<T>(T obj)
{
     var newObj = obj;
     foreach (PropertyInfo p in obj.GetType().BaseType.GetProperties())
     {
         if(p.Name.ToString().ToLower() = "id")
         {
             p.SetValue(newObj,Guid.NewGuid());
         }
     }

    return newObj;
}

这将更新Id员工。

但我还需要更新Employee中所有属性的ID。

任何人都可以帮我吗?

编辑:我已经尝试了循环遍历所有属性并更新Id的技术,但我使用的对象非常大,并且使用这种方法,代码的性能受到很大影响。在某些情况下,完成该过程大约需要几分钟。我正在寻找一种更好的方法来解决这个问题。

1 个答案:

答案 0 :(得分:0)

嗯,你只是通过基础的属性循环,对于该对象,你应该循环遍历对象上的所有属性,然后更新它们

这样的事情:

public static T UpdateClone<T>(T obj)
{
    var newObj = obj;
    foreach (PropertyInfo p in obj.GetType().BaseType.GetProperties())
    {
        if (p.Name.ToString().ToLower() == "id")
        {
            p.SetValue(newObj, Guid.NewGuid());
        }
    }

    foreach (PropertyInfo pInfo in obj.GetType().GetProperties())
    {
        var propertyObject = pInfo.GetValue(obj);
        if (propertyObject != null)
        {
            if (propertyObject is IEnumerable && !(propertyObject is string))
            {
                foreach (object p in (propertyObject as IEnumerable))
                {
                    UpdateClone(p);
                }
            }
            else
            {
                foreach (PropertyInfo p in propertyObject.GetType().BaseType.GetProperties())
                {
                    if (p.Name.ToString().ToLower() == "id")
                    {
                        p.SetValue(propertyObject, Guid.NewGuid());
                    }
                }
            }
        }
    }
  return newObj;
}