ОП! :) Спасибо за попытку, хотя. Просто жаль, что нет области «Друг», как в C ++, но похоже, что по большей части частного интерфейса будет достаточно. Еще раз спасибо!

здаем иерархию объектов, где каждый элемент имеет коллекцию других элементов, и каждый элемент также имеетParent&nbsp;свойство, указывающее на его родительский элемент. Довольно стандартные вещи. У нас также естьItemsCollection&nbsp;класс, который наследуется отCollection<Item>&nbsp;который сам по себе имеетOwner&nbsp;свойство, указывающее на элемент, которому принадлежит коллекция. Опять ничего интересного там нет.

Когда элемент добавляется вItemsCollection&nbsp;класс, мы хотим, чтобы он автоматически установил родителя Item (используя коллекциюOwner&nbsp;свойство) и когда элемент удаляется, мы хотим очистить родительский элемент.

Вот вещь Мы хотим толькоParent&nbsp;сеттер будет доступен дляItemsCollection, ничего больше. Таким образом, мы можем не только узнать, кто является родителем элемента, но мы также можем убедиться, что элемент не добавлен в несколько коллекций, проверив существующее значение вParentили позволить кому-то произвольно изменить его на что-то другое.

Мы знаем, как это сделать двумя способами:

Отметьте сеттер как частный, а затем заключите определение коллекции в область самого элемента. Pro: Полная защита. Con: Гадкий код с вложенными классами.

Используйте личноеISetParent&nbsp;интерфейс на элементе, который толькоItemsCollection&nbsp;знает о. Pro: намного чище код и легко следовать. Con: Технически любой, кто знает об интерфейсе, может разыгратьItem&nbsp;и получить в сеттер.

Теперь технически с помощью размышлений любой может в любом случае достичь чего-либо, но все же ... пытаясь найти лучший способ сделать это.

Теперь я знаю, что в C ++ была функция, называемаяFriend&nbsp;или что-то, что позволит вам назначить другого закрытого члена в одном классе доступным для другого, что было бы идеальным сценарием, но я не знаю ничего подобного в C #.

В псевдокоде (например, все уведомления об изменениях свойств были удалены для краткости, и я просто набираю это здесь, а не копируя из кода), у нас есть это ...

public class Item
{
    public string Name{ get; set; }
    public Item Parent{ get; private set; }
    public ItemsCollection ChildItems;

    public Item()
    {
        this.ChildItems = new ItemsCollection (this);
    }
}

public class ItemsCollection : ObservableCollection<Item>
{
    public ItemsCollection(Item owner)
    {
        this.Owner = owner;
    }   

    public Item Owner{ get; private set; }

    private CheckParent(Item item)
    {
        if(item.Parent != null) throw new Exception("Item already belongs to another ItemsCollection");
        item.Parent = this.Owner; // <-- This is where we need to access the private Parent setter
    }

    protected override void InsertItem(int index, Item item)
    {
        CheckParent(item);
        base.InsertItem(index, item);
    }

    protected override void RemoveItem(int index)
    {
        this[index].Parent = null;
        base.RemoveItem(index);
    }

    protected override void SetItem(int index, Item item)
    {
        var existingItem = this[index];

        if(item == existingItem) return;

        CheckParent(item);
        existingItem.Parent = null;

        base.SetItem(index, item);
    }

    protected override void ClearItems()
    {
        foreach(var item in this) item.Parent = null; <-- ...as is this
        base.ClearItems();
    }

}

Любой другой способ сделать что-то подобное?