C# 如何清理双重链接的多对多关系?

C# 如何清理双重链接的多对多关系?,c#,many-to-many,C#,Many To Many,首先,我不确定这个标题是否准确地描述了我所指的内容,所以请随意留言,或者如果你有代表的话,可以自己重命名 比如说,我有两个班,图书和图书馆。图书馆包含一个属性,该属性是它所拥有的所有书籍的列表。一本书的属性是它所属的所有图书馆的列表 在这本书中,我有一个RemoveFromLibrary方法,可以从它的库列表中删除一个库。我还想用同样的方法清理另一端,即图书馆拥有的图书清单。另一端也是一样,Library上的RemoveBook方法也会清理该书中包含它的库的列表 首先,这有意义吗?对我来说,调用

首先,我不确定这个标题是否准确地描述了我所指的内容,所以请随意留言,或者如果你有代表的话,可以自己重命名

比如说,我有两个班,图书和图书馆。图书馆包含一个属性,该属性是它所拥有的所有书籍的列表。一本书的属性是它所属的所有图书馆的列表

在这本书中,我有一个RemoveFromLibrary方法,可以从它的库列表中删除一个库。我还想用同样的方法清理另一端,即图书馆拥有的图书清单。另一端也是一样,Library上的RemoveBook方法也会清理该书中包含它的库的列表

首先,这有意义吗?对我来说,调用代码不必担心清理,也不必调用两个方法来执行一个逻辑操作似乎很方便。我的意思是从一个列表中删除而不是从另一个列表中删除是没有意义的。同时,可以说这使得它们之间的耦合过于紧密,但我认为如果这成为一个问题,我将进行重构以解耦


至于实现这一点,我不确定的是,如果我只调用普通的public方法,那么我将得到每个方法调用另一个方法的无限循环。我可以创建一个单独的内部属性(在C#中工作)来不进行清理,但感觉就像我在API中乱丢了一个只能从另一个方法调用的方法。或者,我可以将底层集合公开为内部集合,这样会更好一些,但它似乎仍然不理想。有更好的解决方案吗?或者我只需要使用这两个解决方案中的一个,或者确保调用代码本身进行清理?

也许这会起作用。在调用另一个类的
remove
方法之前,请检查它的对象列表(例如书籍)是否仍然包含要删除的对象

顺便说一句这只是伪代码(可能无法编译)


编辑:修复了基于注释的代码。。。写的时候我很困:也许这会有用。在调用另一个类的
remove
方法之前,请检查它的对象列表(例如书籍)是否仍然包含要删除的对象

顺便说一句这只是伪代码(可能无法编译)


编辑:修复了基于注释的代码。。。写这篇文章时我很困:坦白说,如果不是为了某个关键的特定性能优化,这对我来说似乎是一个可疑的设计。我会思考为什么你需要一个或另一个的反向链接(可能是从书到图书馆),并评估你是否可以摆脱它们。我认为,调用代码可以更方便、更自然地删除代码。我不认为这是世界上最好的理由,但我看不出它有任何缺点,所以它看起来像是一个小的优点对没有缺点。但我可能是错的,也可能有我不知道的缺点。坦白说,如果不是为了某个关键的特定性能优化,这对我来说似乎是一个可疑的设计。我会思考为什么你需要一个或另一个的反向链接(可能是从书到图书馆),并评估你是否可以摆脱它们。我认为,调用代码可以更方便、更自然地删除代码。我不认为这是世界上最好的理由,但我看不出它有任何缺点,所以它看起来像是一个小的优点对没有缺点。虽然我可能错了,但也可能有我不知道的缺点。哇。。。既然你指出了这一点,它似乎是如此明显。顺便说一句,在检查/从另一个列表中删除之前,需要先进行本地删除,正如所写的那样,您仍然有一个无限循环,因为if条件始终为true+1的概念,我会接受,如果你修复了它,没有其他人发布更好的答案。同样在RemoveBook(Book bk)中,你有Book.RemovelLibrary(this),当你指的是bk.RemovelLibrary(this)。修复。。不管怎么说,你想到了:)哇。。。既然你指出了这一点,它似乎是如此明显。顺便说一句,在检查/从另一个列表中删除之前,需要先进行本地删除,正如所写的那样,您仍然有一个无限循环,因为if条件始终为true+1的概念,我会接受,如果你修复了它,没有其他人发布更好的答案。同样在RemoveBook(Book bk)中,你有Book.RemovelLibrary(this),当你指的是bk.RemovelLibrary(this)。修复。。不管怎样,你的想法是:)
class Book
{
    Library[] libraries;

    void RemoveFromLibrary(Library lib)
    {
        libraries.remove(lib);
        if (IsInLibrary(lib) && lib.HasBook(this)) // prevents call-loop
            lib.RemoveBook(this);
    }

    bool IsInLibrary(Library lib)
    {
        return libraries.Contain(lib);
    }
}


class Library
{
    Book[] books;

    void RemoveBook(Book bk)
    {
        books.remove(bk);
        if (HasBook(bk) && bk.IsInLibrary(this)) // prevents call-loop
            bk.RemoveLibrary(this);
    }

    bool HasBook(Book bk)
    {
        return books.Contain(bk);
    }
}