Удаление объектов с связями между собой
Суть вопроса. Не могу придумать адекватный подход удаления. В моей ситуации имеются сущности допустим коробка. В коробке могут лежать ещё коробки и тд. В одной коробке может лежать несколько, а в них ещё и тд. Как корректно удалить все. Если к примеру я удаляю самую первую коробку, в которой может лежать N коробок, в которых ещё могут лежать и тд. Все коробки лежат в List<Box>. Пользователь вводит имя коробки, которую необходимо удалить. И нужно удалить все коробки, которые лежат внутри.
public class Box
{
public string NameBox{get;set;}
public string RootNameBox{get;set;}
}
Привел пример класса, которые реализует эту зависимость.
Ответы (1 шт):
Если у вас нет какой либо связанности между объектами (что зря), то ваш алгоритм должен быть примерно такой:
- Берем нужную коробку на удаление.
- Отдаем ее методу удаления.
- Метод удаления ищет коробку/коробки, которые ссылаются на эту коробку удаления и рекурсивно вызывает самого себя.
Простой пример подобной реализации:
Ваш класс коробки (я добавил лишь конструктор)
public class Box { public Box(string name, string rootBox = default) { NameBox = name; RootNameBox = rootBox; } public string NameBox { get; set; } public string RootNameBox { get; set; } }Глобальный список всех коробок (если он не глобальный, то скорей всего придется передавать в метод параметром.
static List<Box> boxes = new List<Box> { new Box("box1"), new Box("box2", "box1"), new Box("box3", "box2"), new Box("box4") };Некий метод удаления (набросал его быстро, чисто показать пример подобного, если в 1 коробке может быть несколько коробок, то берите не первую, а все найденные и прогоняйте их циклом через метод.
static void Delete(Box box) { var rootBox = boxes.FirstOrDefault(x => x.RootNameBox == box.NameBox); if (rootBox != null) { Delete(rootBox); } boxes.Remove(box); }Ну и вызов.
var firstBox = boxes.FirstOrDefault(x => x.NameBox == "box1"); Delete(firstBox);
Имея все это, мы можем приукрасить все и сделать например метод расширения:
public static class Ext
{
public static void DeleteBox(this List<Box> boxes, string boxName)
{
DeleteBox(boxes, boxes.FirstOrDefault(x => x.NameBox == boxName));
}
public static void DeleteBox(this List<Box> boxes, Box box)
{
if (box == null) return;
var rootBox = boxes.FirstOrDefault(x => x.RootNameBox == box.NameBox);
if (rootBox != null)
{
boxes.DeleteBox(rootBox);
}
boxes.Remove(box);
}
}
Тогда вызов будет вообще:
boxes.DeleteBox("box1");
В общем саму суть рекурсии вы поняли, дальше сами дорабатывайте как вам надо. Удачи!
А что ты говорил про связи? Не мог бы подробнее?
Сейчас вы совершенно не знаете что за коробка у вас например будет в box1, ибо только box2 знает о том, что у нее есть "предок". На мой взгляд правильней будет переписать класс коробки на нечто подобное:
public class Box
{
public Box(string name, Box rootBox = default)
{
NameBox = name;
RootBox = rootBox;
}
public string NameBox { get; set; }
public Box RootBox { get; set; }
}
Теперь основная коробка знает о том, что у нее есть дочерняя коробка и так у вас уже выстраивается цепочка зависимостей (box1.RootBox.RootBox.RootBox...).
И тогда нам уже не надо будет искать объект по имени, нам достаточно взять нужную коробку и удалить ее:
static void Delete(Box box)
{
if (box.RootBox != null)
Delete(box.RootBox);
boxes.Remove(box);
}
Инициализация тут будет тогда примерно следующая:
var box4 = new Box("box4");
var box3 = new Box("box3");
var box2 = new Box("box2", box3);
var box1 = new Box("box1", box2);
boxes = new List<Box> { box1, box2, box3, box4 };
box1ссылается наbox2.box2ссылается наbox3.box3иbox4являются простыми коробками, без ссылок.
Вызываем метод удаления для удаления первой коробки:
Delete(box1);
и в результате у нас останется только box4.