2017-02-22 7 views
0

아래 클래스를 사용하여 직렬화를 사용하지 않고 딥 복제를 수행합니다.리플렉션을 사용한 컬렉션 (키/값 쌍)의 완전 복제

public class AbstractClone 
{ 

    public AbstractClone Clone() 
    { 
     Type typeSource = this.GetType(); 
     AbstractClone tObject = (AbstractClone)FormatterServices.GetUninitializedObject(typeSource); 

     PropertyInfo[] propertyInfo = typeSource.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); 

     foreach (PropertyInfo property in propertyInfo) 
     { 
      if (property.CanWrite) 
      { 

       if (property.PropertyType.IsValueType || property.PropertyType.IsEnum || property.PropertyType.Equals(typeof(System.String))) 
       { 
        property.SetValue(tObject, property.GetValue(this, null), null); 
       } 
       else 
       { 
        object objPropertyValue = property.GetValue(this, null); 

        if (objPropertyValue == null) 
        { 
         property.SetValue(tObject, null, null); 
        } 
        else 
        { 
         property.SetValue(tObject, ((AbstractClone)objPropertyValue).Clone(), null); 
        } 
       } 
      } 

     } 
     return tObject; 
    } 
} 

복제해야하는 모든 클래스를 상속합니다.

사람이 사전의 SortedList 같은 키 값 쌍을 복제 할 수있는 방법을 제안 할 수 등 SortedList, 사전 같은 키 값 쌍 또는 컬렉션을 제외한 모든 객체와 잘 작동합니다.

답변

0

딥 복사는 심각한 작업입니다. 우선, 귀하의 솔루션은 귀하의 유형을 상속해야하므로 사용하기가 불가능할 수도 있으며 제 3 자 클래스를 상속받을 수도 없습니다. 두 번째 문제는 참으로 깊은되지 않는 것입니다 : 당신은 모든 참조를 복사합니다 :

class Employee 
{ 
    public string Name {get; set;} 
    public Position Position {get; set;} 
} 
class Position 
{ 
    public string Name {get;set;} 
    public int ID {get;set;} 
} 

당신이 원래의 목적에 Name 부동산 재산 Position의를 변경하는 경우, 당신은 당신의 사본에 변경 사항을 볼 수 있습니다. 그리고 속성을 재귀 적으로 실행하도록 솔루션을 업그레이드하려고하면주기 참조를 처리해야합니다.

그러나이 작업은 이미 완료되었으므로 준비 솔루션을 찾아야합니다 (예 : this one).