1 odpowiedź

Kopia płytka obiektu jest realizowana np. w metodzie MemberwiseClone, której działanie polega na stworzeniu nowej instancji obiektu, a następnie przekopiowanie do niej wszystkich właściwości obiektu. W przypadku typów wartościowych są one kopiowane bit po bicie, czyli faktycznie otrzymujemy kopię tej właściwości, ale w przypadku typów referencyjnych są kopiowane tylko referencje do nich, a nie same obiekty. Dlatego też kopia płytka zwraca nam obiekt, którego właściwości, jeśli są typami referencyjnymi, to wskazują na te same obiekty, na które wskazują właściwości w obiekcie oryginalnym. Przykład implementacji płytkiej kopii (dla klasy zawierającej tylko właściwość wartościową):

public class Person : ICloneable
{
    public int Age;
    public object Clone()
    {
        return this.MemberwiseClone();
    }
}

class Program
{
    static void Main(string[] args)
    {
        var programmer = new Person();
        programmer.Age = 28;
        var programmer_bis = (Person)programmer.Clone(); //obiekt zwrócony przez metodę MemberwiseClone jest typu object, dlatego trzeba go rzutować
    }
}

Nie zawsze jednak jest to to, co chcemy osiągnąć, dlatego metoda MemberwiseClone przydaje się na ogół dla tych obiektów, które mają tylko właściwości o typach wartościowych. Jeśli natomiast chcemy mieć dwa zupełnie odrębne obiekty, które nie mają ze sobą żadnych referencji wspólnie wskazujących na ten sam obiekt, to musimy zrealizować kopię głęboką. Najprostsza implementacja kopii głębokiej polega na jawnym przekopiowaniu każdej właściwości, a jeśli ta właściwość jest typu referencyjnego, to należy przekopiować nie samą referencję, a wartości które ona przechowuje (czyli de facto należy zejść do poziomu w którym będziemy kopiować już tylko typy wartościowe). Np.

public class Identity
{
    public string Name;
}

public class Person
{
    public Identity Identity;
    public int Age;

    public Person()
    {
        this.Identity = new Identity();
    }

    public Person DeepCopy()
    {
        var temporary = new Person();
        temporary.Age = this.Age;
        temporary.Identity.Name = this.Identity.Name; //trzeba przekopiować właściwość obiektu Identity 
        return temporary;
    }
}

Przedstawiony powyżej przykład na realizację kopii głębokiej jest najprostszym sposobem jej implementacji. Jego główną wadą jest to, że w przypadku gdy do klasy dojdą kolejne właściwości, to trzeba pamiętać, aby edytować metodę DeepCopy. Dlatego do klonowania obiektów w C# używa się również innych sposobów, np. serializację i deserializację, wywołując jedną po drugiej, bądź refleksję.

Zaloguj się lub zarejestruj by dodać odpowiedź.


© 2019 - SkillsTest.pl | | Regulamin | Polityka Prywatnosci