2009-09-15 12 views
9

In particolare, qualcuno può darmi esempi concreti di quando o quando non utilizzare le classi annidate?Quando vuoi nidificare le classi in C#?

Conosco da sempre questa funzione, ma non ho mai avuto motivo di usarla.

Grazie.

+0

domanda simile - http://stackoverflow.com/questions/48872/why-when-should-you-use-nested-classes-in-net-or-shouldnt-you – Nate

risposta

16

Quando la classe nidificata viene utilizzata solo dalla classe esterna, un grande esempio, non più necessario, è per una classe di enumerazione per una raccolta.

altro esempio potrebbe essere per un enum per sostituire un vero falso parametro utilizzato con un metodo all'interno di una classe, per chiarire la firma chiamata ...

invece di

public class Product 
{ 
    public void AmountInInventory(int warehouseId, bool includeReturns) 
    { 
     int totalCount = CountOfNewItems(); 
     if (includeReturns) 
      totalCount+= CountOfReturnedItems(); 
     return totalCount; 
    } 
} 

e

product P = new Product(); 
    int TotalInventory = P.AmountInInventory(123, true); 

che non chiarisce cosa significa "vero", è possibile scrivere:

public class Product 
{ 
    [Flags]public enum Include{None=0, New=1, Returns=2, All=3 } 
    public void AmountInInventory(int warehouseId, Include include) 
    { 
     int totalCount = 0; 
     if ((include & Include.New) == Include.New) 
      totalCount += CountOfNewItems(); 
     if ((include & Include.Returns) == Include.Returns) 
      totalCount += CountOfReturns(); 
     return totalCount; 
    } 
} 


    product P = new Product(); 
    int TotalInventory = P.AmountInInventory(123, Product.Include.All); 

Ciò rende il valore del parametro azzerato nel codice client.

2

Ho visto casi di classi annidate quando una struttura di dati di scopo speciale viene utilizzata solo all'interno di una classe, oppure viene generata una certa eccezione e viene catturata solo all'interno di una classe.

11

I due luoghi in cui ho utilizzare le classi nidificate:

  • La classe annidata è utilizzato esclusivamente dalla classe esterna, e voglio ambito completamente privato.

  • La classe nidificata viene utilizzata specificamente per implementare un'interfaccia definita altrove. Ad esempio, l'implementazione di un enumeratore rientra in questa categoria.

3

a volte lo uso per semplici classi di supporto che ho bisogno di una funzione o due all'interno della classe padre.

1

I nidificare classi quando ho una classe di supporto che non ha bisogno di essere visibile a qualsiasi altro oggetto nel sistema. Ciò mantiene la visibilità il più possibile limitata che aiuta a prevenire usi indesiderati della classe

4

In realtà si desidera utilizzare solo classi nidificate quando si è sicuri che la classe nidificata non abbia senso che possa essere utilizzata in qualsiasi altro luogo.

Ad esempio, se è necessario creare un elenco di diversi tipi di oggetti associati insieme a funzioni e informazioni sui membri di quell'insieme di oggetti per un breve periodo (come metodi o proprietà), è possibile utilizzare una classe nidificata da eseguire quella. Forse hai bisogno di creare un elenco di tutte le combinazioni di qualche tipo di oggetto e quindi contrassegnare tutte le combinazioni che hanno una certa proprietà. Sarebbe un buon caso per una classe annidata.

Se non hai bisogno di metodi sulla classe annidata, probabilmente puoi semplicemente usare una struttura ma non so se IL li tratti in modo diverso.

1

Le "regole" dello zio Bob sulla coesione dovrebbero rilevare che in realtà si creano un certo numero di classi annidate (e nidificate, nidificate!). Questi potrebbero essere essere non nidificati ma solo se ci sono altri client che li fanno riferimento ora.

1

Mi piacerebbe migliorare la mia risposta precedente!

Un'area specifica in cui utilizzo regolarmente classi annidate abilita l'interfaccia Injection e Inversion of Control. Esempio ...

public class Worker 
{ 
    private IHelper _helper; 

    public Worker() 
    : this (new DefaultHelper()) 
    { 
    } 
    public Worker(IHelper helper) 
    { 
    this._helper = helper; 
    } 

    private class DefaultHelper : IHelper 
    { 
    } 
}