Klonowanie listy

0

Mam problem z klonowaniem listy. Tak po prawdzie, to w ogóle nie wiem czy da się zrobić to, o co mi chodzi :)
Chciałbym sklonować listę obiektów, gdzie każdy z obiektów posiada referencję do listy obiektów. Chciałbym mieć wierną kopię ze wszystkimi powiązaniami ale z możliwością powrotu do stanu początkowego jak już coś namieszam. Po co mi to?
Rozwiązuje sobie takie fajne zadanka na codingame, (konkretnie https://www.codingame.com/training/hard/vox-codei-episode-1). Zadanie przedstawione jest tak: mamy planszę x na y, na tej planszy poustawiane są elementy, które należy zniszczyć poprzez ustawienie w ich pobliżu bomby. Bomb jest oczywiście ograniczona ilość i podkładamy je jedna na turę.. Ogólnie bez większych problemów można wyznaczyć sobie lokację w której pozostawienie bomby będzie siało największe zniszczenie. W 10 przypadkach na 12 to wystarczy, tzn. podążanie tropem największych destrukcji prowadzi do prawidłowego rozwiązania. Pozostają jednak dwa przypadki, dla których to nie zadziała... Chciałbym więc przed "podłożeniem bomby" przeprowadzić symulację, jak się to wszystko rozwinie.
Stworzyłem sobie klasę Point, reprezentującą punkt na planszy. Klasa posiada pole List<Point> affectedNodes, gdzie znajdują się referencję do wszystkich punktów "celów", które ulegną zniszczeniu w przypadku umieszczenia bomby w punkcie. Działa to oczywiście dynamicznie, jeśli umieszczę bombę w punkcie, to automatycznie zaktualizuje mi się info o celach w innych punktach. Wszystkie punkty trzymam na liście. W celu przeprowadzenia symulacji muszę stworzyć wierną kopię listy wszystkich punktów, i przetestować ścieżkę. Tylko nie wiem jak się za to klonowanie zabrać.
klasa Point wygląda tak:

    class Point
    {
        private int x, y;
        private List<Point> affectedNodes; //lista sąsiednich celów które zostaną zniszczone w przypadku wybuchu w tym punkcie 

        public int X { get => x; }
        public int Y { get => y; }

        public int PotentialDamage { get => affectedNodes.Count(n => n.Type == PointType.node); } 
        public PointType Type { get; set; } // type of point

        public Point(int x, int y, char type)
        {
            this.x = x;
            this.y = y;
            affectedNodes = new List<Point>();
            if (type == '#')
                Type = PointType.indestuctible;
            else if (type == '@')
                Type = PointType.node;
            else
                Type = PointType.empty;
        }

        internal void SetDependencies(Point[,] map)
        {
            int height = map.GetLength(0);
            int width = map.GetLength(1);
            Point otherPoint;
            // looking in 4 directions, 3 points each
            for (int i = 1; i < 4; i++)
            {
                if (x + i >= width)
                    break;
                otherPoint = map[y, x + i];
                if (otherPoint.Type == PointType.indestuctible)
                    break;
                else if (otherPoint.Type == PointType.node)
                    this.affectedNodes.Add(otherPoint);
            }
            for (int i = 1; i < 4; i++)
            {
                if (x - i < 0)
                    break;
                otherPoint = map[y, x - i];
                if (otherPoint.Type == PointType.indestuctible)
                    break;
                else if (otherPoint.Type == PointType.node)
                    this.affectedNodes.Add(otherPoint);
            }
            for (int i = 1; i < 4; i++)
            {
                if (y + i >= height)
                    break;
                otherPoint = map[y + i, x];
                if (otherPoint.Type == PointType.indestuctible)
                    break;
                else if (otherPoint.Type == PointType.node)
                    this.affectedNodes.Add(otherPoint);
            }
            for (int i = 1; i < 4; i++)
            {
                if (y - i < 0)
                    break;
                otherPoint = map[y - i, x];
                if (otherPoint.Type == PointType.indestuctible)
                    break;
                else if (otherPoint.Type == PointType.node)
                    this.affectedNodes.Add(otherPoint);
            }
        }

        internal void Explode()
        {
            foreach (var node in affectedNodes)
            {
                node.Type = PointType.empty;
            }
        }
    }

W zasadzie to zadanie "zaliczyłem", ale nie do końca po bożemu :)

2
public static class CloneTool
    {
        public static T DeepClone<T>(this T obj)
        {
            using (var ms = new System.IO.MemoryStream())
            {
                var formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                formatter.Serialize(ms, obj);
                ms.Position = 0;

                return (T)formatter.Deserialize(ms);
            }
        }
    }

Użycie:

var klon = cokolwiek.DeepClone();

Klasę którą klonujesz musisz oznaczyć jako [Serializable]

1 użytkowników online, w tym zalogowanych: 0, gości: 1