1. ホーム
  2. c#

C#のプライベートインナークラス - なぜもっと使われないのか?

2023-09-02 11:12:26

疑問点

私はC#の比較的新しい人間ですが、C#のプロジェクトに取り組み始めるたびに(C#ではほぼ成熟したプロジェクトしか手がけたことがありません)、なぜインナークラスがないのだろうか?

たぶん、私は彼らの目標を理解していないのでしょう。私にとっては、内部クラス (少なくともプライベート内部クラス) は Pascal や Modula-2 や Ada における "inner procedures" によく似ています。

例: ほとんどの場合、次のようなものがあります。

public class ClassA
{
   public MethodA()
   {
      <some code>
      myObjectClassB.DoSomething(); // ClassB is only used by ClassA
      <some code>
   }
}

public class ClassB
{
   public DoSomething()
   {
   }
}

ClassBは(少なくともしばらくの間は)ClassAによってのみ使用されるので、このコードは以下のように表現するのが良いのではないかと思います。

   public class ClassA
   {
      public MethodA()
      {
         <some code>
         myObjectClassB.DoSomething(); // Class B is only usable by ClassA
         <some code>
      }

      private class ClassB
      {
         public DoSomething()
         {
         }
      }
   }

このテーマについてお聞かせいただければ幸いです - 私の考えは正しいでしょうか?

どのように解決するのですか?

ネストされたクラス (C# のネストされたクラスは Java の内部クラスと多少異なるため、おそらく "inner" という言葉は避けたほうがよいでしょう) は確かに非常に便利です。

言及されていないパターンとして、"better enum"パターンがあり、これはJavaのものよりもさらに柔軟であることができます。

public abstract class MyCleverEnum
{
    public static readonly MyCleverEnum First = new FirstCleverEnum();
    public static readonly MyCleverEnum Second = new SecondCleverEnum();

    // Can only be called by this type *and nested types*
    private MyCleverEnum()
    {
    }

    public abstract void SomeMethod();
    public abstract void AnotherMethod();

    private class FirstCleverEnum : MyCleverEnum
    {
        public override void SomeMethod()
        {
             // First-specific behaviour here
        }

        public override void AnotherMethod()
        {
             // First-specific behaviour here
        }
    }

    private class SecondCleverEnum : MyCleverEnum
    {
        public override void SomeMethod()
        {
             // Second-specific behaviour here
        }

        public override void AnotherMethod()
        {
             // Second-specific behaviour here
        }
    }
}

ここでは紹介していませんが、実際にはすべての値に対して入れ子クラスを使用しないとか、複数の値に対して同じ入れ子クラスを使用し、それぞれに異なるコンストラクタ引数を与えるなど、多くのオプションがあります。しかし基本的には、入れ子クラスが private コンストラクタを呼び出すことができるという事実が、多くの力を与えてくれるのです。