How to overcome lack of friendship in C#?

I quite like the friendship feature of C++. Say, we have a Parent and Child. Child's ctor takes a Parent as a parameter:

Child::Child(Parent & parent)
{
    // Parent::RegisterChild is private
    parent.RegisterChild(this);
}

Due to friendship, Parent and Child may maintain quite secure control over themselves - for example, when Child changes Parent, it may inform previous Parent, that it wants to be detached from its Child list and the new Parent, that it wants to be attached to its list. The security in this solution means, that no class deriving from Parent or Child may break this mechanism.

Unfortunately, C# does not provide such feature as friendship. There is a internal access modifier, but it restricts visibility of classes elements to the assembly, so if one extends the assembly and introduces new classes, the mechanism will no longer be safe. And extracting such classes to separate assembly just to provide security seems to be a very messy idea.

Is there a way to use existing C# mechanisms to provide such close and secure cooperation between two classes, which cannot be broken in derived classes?


Edit: In response to comments

This is not a matter of trust, because - as Eric stated - people, who have access to source code can always break it (remove private modifiers, add another friend classes, whatever). This is a security measure designed to prevent people from making simple, stupid mistakes, which are later hard to track. I use friends to create isolated mechanisms, embedded in base classes, which cannot be (or at least cannot easily) be broken in derived classes. That way neither I nor my coworkers don't have to worry about these anymore.

Jon Skeet
people
quotationmark

The only type-based access would be nested types. If you nest one type within another, the nested type has access to all the members of the enclosing class, including private members. The nested type can also be private. For example:

public class Outer
{
    // Code outside the body of Outer cannot call this. But
    // the code in Nested *is* inside the body of Outer, so it's okay.
    private void Foo()
    {
    }

    private class Nested
    {
        internal void Bar()
        {
            new Outer().Foo();
        }
    }
}

That can be helpful in some cases, but obviously isn't a general replacement for the concept of "friend" classes in C++.

One thing to be aware of is InternalsVisibleToAttribute, which allows one assembly access to the internal members of another. I realize in your case you actually want more restricted access than internal, but [InternalsVisibleTo] is still worth knowing about - it's particularly useful for testing.

people

See more on this question at Stackoverflow