9

コンテナクラスと外部クラスにアクセスできるネストされたクラスを定義しようとしていますが、コンテナクラスのインスタンスのみがネストされたクラスの新しいインスタンスを作成できるように、ネストされたクラスのインスタンス化を制御したいと思います。

進行中のコードは、うまくいけばこれを実証するはずです:

public class Container
{
    public class Nested
    {
        public Nested() { }
    }

    public Nested CreateNested()
    {
        return new Nested();  // Allow
    }
}

class External
{
    static void Main(string[] args)
    {
        Container containerObj = new Container();
        Container.Nested nestedObj;

        nestedObj = new Container.Nested();       // Prevent
        nestedObj = containerObj.CreateNested();  // Allow

    }
}

Nestedがアクセスできるようにするには、パブリックである必要がありますExternal。の基本クラスではないため、 Nestedprotectedのコンストラクターを作成しようとしましたが、Containerインスタンスを作成できません。のコンストラクターをに設定することもできますが、同じアセンブリ内のクラスを含むすべての外部クラスによるコンストラクターへのアクセスを防止しようとしています。これを行う方法はありますか?ContainerNestedNestedinternal

アクセス修飾子を使用してこれを実現できない場合は、内で例外をスローできるかどうか疑問に思いますNested()new Nested()ただし、呼び出されるコンテキストをテストする方法がわかりません。

4

2 に答える 2

11

インターフェイスを介した抽象化はどうですか?

public class Container
{
    public interface INested
    {
        /* members here */
    }
    private class Nested : INested
    {
        public Nested() { }
    }

    public INested CreateNested()
    {
        return new Nested();  // Allow
    }
}

class External
{
    static void Main(string[] args)
    {
        Container containerObj = new Container();
        Container.INested nestedObj;

        nestedObj = new Container.Nested();       // Prevent
        nestedObj = containerObj.CreateNested();  // Allow

    }
}

抽象基本クラスでも同じことができます。

public class Container
{
    public abstract class Nested { }
    private class NestedImpl : Nested { }
    public Nested CreateNested()
    {
        return new NestedImpl();  // Allow
    }
}

class External
{
    static void Main(string[] args)
    {
        Container containerObj = new Container();
        Container.Nested nestedObj;

        nestedObj = new Container.Nested();       // Prevent
        nestedObj = containerObj.CreateNested();  // Allow

    }
}
于 2012-10-19T13:16:26.233 に答える
1

このようにクラスを宣言することは不可能です。クラスをプライベートとして宣言し、パブリックインターフェイスを介して公開するのが最善の方法だと思います。

class Program
{
    static void Main(string[] args)
    {
       // new S.N(); does not work
        var n = new S().Create();
    }
}

class S
{
    public interface IN
    {
        int MyProperty { get; set; }
    }
    class N : IN
    {
        public int MyProperty { get; set; }
        public N()
        {

        }
    }

    public IN Create()
    {
        return new N();
    }
}
于 2012-10-19T13:16:58.060 に答える