Domanda

Sono relativamente nuovo in C # e ogni volta che inizio a lavorare su un progetto C # (ho lavorato solo su progetti quasi maturi in C #) Mi chiedo perché non ci siano classi interne?

Forse non capisco il loro obiettivo. Per me, le classi interne - almeno le classi interne private - assomigliano molto a "procedure interne". in Pascal / Modula-2 / Ada: consentono di scomporre una classe principale in parti più piccole al fine di facilitare la comprensione.

Esempio: ecco cosa si vede il più delle volte:

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

public class ClassB
{
   public DoSomething()
   {
   }
}

Poiché ClassB verrà utilizzato (almeno per un po ') solo da ClassA, la mia ipotesi è che questo codice sarebbe meglio espresso come segue:

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

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

Sarei felice di sentirti su questo argomento - Ho ragione?

È stato utile?

Soluzione

Le classi nidificate (probabilmente è meglio evitare la parola "interno" poiché le classi nidificate in C # sono in qualche modo diverse dalle classi interne in Java) possono davvero essere molto utili.

Un modello che non è stato menzionato è il "migliore enum" modello - che può essere persino più flessibile di quello in 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
        }
    }
}

Potremmo fare un po 'di supporto linguistico per eseguire alcune di queste operazioni automaticamente - e ci sono molte opzioni che non ho mostrato qui, come non usare effettivamente una classe nidificata per tutti i valori o usare la stessa classe nidificata più valori, ma dando loro diversi parametri del costruttore. Ma in sostanza, il fatto che la classe nidificata possa chiamare il costruttore privato dà molta potenza.

Altri suggerimenti

Le Linee guida per la progettazione del framework hanno le regole migliori per l'utilizzo di classi nidificate che I trovato fino ad oggi.

Ecco un breve elenco di riepilogo:

  
      
  1. Usa i tipi nidificati quando la relazione tra tipo e tipo nidificato è tale che si desidera la semantica dell'accessibilità dei membri.

  2.   
  3. NON usa tipi nidificati pubblici come costrutto di gruppi logici

  4.   
  5. Evita l'uso di tipi nidificati esposti pubblicamente.

  6.   
  7. NON usa tipi nidificati se è probabile che si faccia riferimento al tipo al di fuori del tipo contenente.

  8.   
  9. NON usa tipi nidificati se devono essere istanziati dal codice client.

  10.   
  11. NON definisce un tipo nidificato come membro di un'interfaccia.

  12.   

Dovresti limitare le responsabilità di ogni classe in modo che ognuna rimanga semplice, testabile e riutilizzabile . Le classi interne private vanno contro questo. Contribuiscono alla complessità della classe esterna, non sono verificabili e non sono riutilizzabili.

Per me personalmente creo classi interne private solo se ho bisogno di creare raccolte in-process di un oggetto che potrebbe richiedere dei metodi su di esse.

Altrimenti, potrebbe causare confusione per gli altri sviluppatori che lavorano al progetto di trovare effettivamente queste classi, poiché non sono molto chiari su dove si trovano.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top