2016-03-30 6 views
0

ich eine folgende Basisklassedie Eigenschaft Basisklasse zu aktualisieren, während tief Klonen

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

Ich habe Anzahl der Kind-Klasse, die von dieser Basisklasse erben. Zum Beispiel:

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;} 
} 

Jetzt brauche ich eine tiefe Kopie von Mitarbeiter-Objekt zu erstellen und muß Id-Feld für alle Eigenschaften aktualisieren, die von BaseEntity Klasse vererbt werden.

ich folgenden Code verwenden es zu implementieren, aber es funktioniert nicht:

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; 
} 

Dies wird die Id Mitarbeiter aktualisieren.

Aber ich muss Ids aller Eigenschaften in Mitarbeiter auch aktualisieren.

Kann mir jemand dabei helfen?

Bearbeitet: Ich habe bereits Technik der Schleife durch alle Eigenschaften und Aktualisierung Id versucht, aber das Objekt, das ich benutze, ist sehr groß und mit diesem Ansatz wird die Leistung des Codes viel getroffen. In einigen Fällen dauert es einige Minuten, bis der Prozess abgeschlossen ist. Ich suche nach einem besseren Ansatz, um dieses Problem zu beheben.

+1

Alternativ können Sie das Kopierkonstruktormuster verwenden, das mit der Vererbung arbeitet. Wenn Sie jedoch viele Klassen haben, wird es mühsam, weil Sie daran denken müssen, den Kopierkonstruktor für alle diese Klassen zu implementieren. Nur ein Gedanke. –

+0

Ja, ich habe viele Klassen und alle Klassen haben viele Felder darin. Ich habe alle Eigenschaften durchgeschleift und die ID aktualisiert, aber ich habe damit eine Menge Leistung. –

+0

Nun, mit 'UpdateClone ' durchlaufen Sie immer noch alle Eigenschaften, so dass das immer noch nicht besser ist. Wenn Sie viele Eigenschaften in jedem Typ aktualisieren müssen, werden Sie mit Bootloads von speziellen Fällen in 'UpdateClone ' enden. Das sieht auch nicht sehr gut aus. An dieser Stelle würde ich es dezentralisieren. Es gibt ein Gleichgewicht, das Sie treffen müssen, viel Platz den gleichen Code -> zentralisieren/abstrahieren. Ein Ort, viele Sonderfälle -> Dezentralisierung. –

Antwort

0

Nun Sie Looping nur durch die Eigenschaften der Basis, dass für das Objekt, sollten Sie eine Schleife durch alle Eigenschaften, die auf dem Objekt, und dann aktualisieren, um sie

Etwas wie folgt aus:

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; 
} 
+0

Danke, ich habe diesen Ansatz bereits ausprobiert. Die Leistung wird mit diesem Ansatz stark getroffen. Objekte, die ich verwende, sind sehr groß, manchmal dauert der Klonprozess selbst einige Minuten. Ich suche nach einem besseren Ansatz. –

+0

Wenn das der Fall ist, empfehle ich, in das Prototyp-Design-Muster zu schauen, vielleicht hilft dies https://sourcemaking.com/design_patterns/prototype – Vnvizitiu