Les classes internes privées en C # - pourquoi ne sont-elles pas utilisées plus souvent?

StackOverflow https://stackoverflow.com/questions/454218

  •  19-08-2019
  •  | 
  •  

Question

Je suis relativement nouveau en C # et chaque fois que je commence à travailler sur un projet C # (je n'ai travaillé que sur des projets presque mûrs en C #), je me demande pourquoi il n'y a pas de classes internes?

Peut-être que je ne comprends pas leur objectif. Pour moi, les classes internes - du moins les classes internes privées - ressemblent beaucoup à des "procédures internes". en Pascal / Modula-2 / Ada: ils permettent de décomposer une classe principale en parties plus petites afin de faciliter la compréhension.

Exemple: voici ce que l'on voit la plupart du temps:

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

public class ClassB
{
   public DoSomething()
   {
   }
}

Etant donné que ClassB sera utilisé (au moins pendant un certain temps) uniquement par ClassA, je suppose que ce code serait mieux exprimé comme suit:

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

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

Je serais heureux d'avoir de vos nouvelles sur ce sujet - Ai-je raison?

Était-ce utile?

La solution

Les classes imbriquées (il est probablement préférable d'éviter le mot "interne", car les classes imbriquées en C # diffèrent quelque peu des classes internes en Java) peuvent en effet être très utiles.

Un motif qui n’a pas été mentionné est le "meilleur enum". pattern - qui peut être encore plus flexible que celui de 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
        }
    }
}

Nous pourrions utiliser un support linguistique pour le faire automatiquement - et de nombreuses options que je n’ai pas présentées ici, telles que ne pas utiliser une classe imbriquée pour toutes les valeurs, ou utiliser la même classe imbriquée pour plusieurs valeurs, mais en leur donnant différents paramètres de constructeur. Mais fondamentalement, le fait que la classe imbriquée puisse appeler le constructeur privé donne beaucoup de pouvoir.

Autres conseils

Les Consignes de conception de framework contiennent les meilleures règles d'utilisation des classes imbriquées que je ont trouvé à ce jour.

Voici une brève liste récapitulative:

  
      
  1. Utilisez des types imbriqués lorsque la relation entre type et type imbriqué est telle que la sémantique d’accessibilité des membres est souhaitée.

  2.   
  3. Ne PAS utilisez-vous des types imbriqués publics en tant que construction de groupe logique

  4.   
  5. Évitez d'utiliser des types imbriqués exposés publiquement.

  6.   
  7. Ne PAS utilisez des types imbriqués si le type est susceptible d'être référencé en dehors du type contenant.

  8.   
  9. Ne PAS utilisez les types imbriqués s'ils doivent être instanciés par le code client.

  10.   
  11. Ne PAS définissez un type imbriqué en tant que membre d'une interface.

  12.   

Vous devez limiter les responsabilités de chaque classe afin que chacune d’elles reste simple, testable et réutilisable . Les classes internes privées vont à l'encontre de cela. Ils contribuent à la complexité de la classe externe, ils ne sont pas testables et ils ne sont pas réutilisables.

Personnellement, je ne crée des classes internes privées que si j'ai besoin de créer des collections in-process d'un objet pouvant nécessiter des méthodes.

Sinon, les autres développeurs travaillant sur le projet pourraient trouver ces classes avec confusion, car elles ne sont pas très claires quant à leur emplacement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top