C#中的朋友类用例的解决方法

kaa*_*lus 12 .net c#

请考虑以下代码模式:

// Each foo keeps a reference to its manager
class Foo
{
    private FooManager m_manager;
}

// Manager keeps a list of all foos
class FooManager
{
    private List<Foo> m_foos;
}
Run Code Online (Sandbox Code Playgroud)

问题:没有办法创建一个新的Foo并更新FooManager中的m_foos列表和新Foo实例中的m_manager引用,而不公开公开一些私有(并冒着某人用实际Foos取消列表的风险).

例如,可以在Foo中实现构造函数Foo(FooManager manager).它可以设置m_manager引用,但无法访问m_foos列表.或者您可以在管理器中实现CreateFoo()方法.它可以访问m_foos列表,但无法在Foo中设置m_manager.

在C++中,显然会声明FooManager是Foo的朋友来表达设计意图,但这在C#中是不可能的.我也知道我可以让Foo成为FooManager的内部类以获得访问权限,但这也不是一个解决方案(如果Foo可以属于多个经理类怎么办?)

顺便说一句.我知道.NET中的"内部"访问,但它要求Foo和FooManager独立存在于一个单独的程序集中,这是不可接受的.

没有公开私有东西的任何变通办法吗?

Pet*_*lin 7

如果我理解正确:

public abstract class FooBus
{
    protected static FooBus m_bus;
}

public sealed class Foo : FooBus
{
    private FooManager m_manager;

    public Foo(FooManager fm)
    {
        if (fm == null)
        {
            throw new ArgumentNullException("Use FooManager.CreateFoo()");
        }

        if (m_bus != fm)
        {
            throw new ArgumentException("Use FooManager.CreateFoo()");
        }

        m_manager = fm;
    }
}

public class FooManager : FooBus
{
    private List<Foo> m_foos = new List<Foo>();

    public Foo CreateFoo()
    {
        m_bus = this;
        Foo f = new Foo(this);
        m_foos.Add(f);
        m_bus = null;

        return f;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 好吧,这不是一个好的解决方案,因为有人可以直接调用新的Foo(),而m_foos列表将无效.(顺便说一下,我知道在Foo构造函数面前公开) (2认同)