Enforcing parent-child relationship in C# and .Net

后端 未结 5 682
夕颜
夕颜 2020-12-14 23:29

Let\'s take the following two classes:

public class CollectionOfChildren
{
    public Child this[int index] { get; }
    public void Add(Child c);
}

public          


        
5条回答
  •  长情又很酷
    2020-12-15 00:28

    Could this sequence work for you?

    • call CollectionOfChild.Add(Child c)
    • add the child to the internal collection
    • CollectionOfChild.Add invokes Child.UpdateParent(this)
    • Child.UpdateParent(CollectionOfChild newParent) calls newParent.Contains(this) to make sure the child is in that collection then change the backing of Child.Parent accordingly. Also have to call CollectionOfChild.Remove(this) to remove itself from the old parent's collection.
    • CollectionOfChild.Remove(Child) would check Child.Parent to make sure it's not the child's collection anymore before it would remove the child from the collection.

    Putting some code down:

    public class CollectionOfChild
    {
        public void Add(Child c)
        {
            this._Collection.Add(c);
            try
            {
                c.UpdateParent(this);
            }
            catch
            {
                // Failed to update parent
                this._Collection.Remove(c);
            }
        }
    
        public void Remove(Child c)
        {
            this._Collection.Remove(c);
            c.RemoveParent(this);
        }
    }
    
    public class Child
    {
        public void UpdateParent(CollectionOfChild col)
        {
            if (col.Contains(this))
            {
                this._Parent = col;
            }
            else
            {
                throw new Exception("Only collection can invoke this");
            }
        }
    
        public void RemoveParent(CollectionOfChild col)
        {
            if (this.Parent != col)
            {
                throw new Exception("Removing parent that isn't the parent");
            }
            this._Parent = null;
        }
    }
    

    Not sure if that works but the idea should. It effectively creates and internal method by using Contains as the child's way to check the "authenticity" of the parent.

    Keep in mind you can blow all this away with reflection so you really only need to make it slightly hard to get around to deter people. Thomas' use of explicit interfaces is another way to deter, though I think this is a bit harder.

提交回复
热议问题