c# - Qual è il modo migliore di accedere al campo nella classe che racchiude dalla classe nidificata?



.net inner-classes (6)

Dire se ho un menu a discesa in un modulo e ho un'altra classe annidata all'interno di questa classe. Ora qual è il modo migliore per accedere a questo menu a discesa dalla classe nidificata?


Answer #1

È possibile passare la classe di inclusione come parametro al costruttore della classe nidificata, in questo modo:

private NestedClass _nestedClass;
public ParentClass() 
{
   _nestedClass = new NestedClass(this);
}

Generalmente le classi annidate non sono raccomandate e dovrebbero essere private e / o interne. Sono, a mio parere, utili a volte però.


Answer #2

A differenza di Java, in C # non vi è alcun riferimento implicito a un'istanza della classe che include.

È necessario passare tale riferimento alla classe annidata. Un modo tipico per farlo è attraverso il costruttore della classe nidificata.

public partial class Form1 : Form
{
    private Nested m_Nested;

    public Form1()
    {
        InitializeComponent();

        m_Nested = new Nested(this);
        m_Nested.Test();
    }

    private class Nested
    {
        private Form1 m_Parent;

        protected Form1 Parent
        {
            get
            {
                return m_Parent;
            }
        }

        public Nested(Form1 parent)
        {
            m_Parent = parent;
        }

        public void Test()
        {
            this.Parent.textBox1.Text = "Testing access to parent Form's control";
        }
    }
}

Answer #3

Correggimi se sbaglio, stai cercando di elaborare il controllo esterno dalla classe interna, quindi ti sei imbattuto in questo. Un modo migliore per farlo sarebbe gestire gli affari in un modo guidato dagli eventi. Utilizzare un pattern Observer, registrare un listener sul controllo esterno (la classe nidificata / interna sarà l'ascoltatore). Rende la vita più semplice. Ho paura che questa non sia la risposta che ti aspettavi!


Answer #4

Membri statici

Dal momento che nessuno lo ha menzionato finora: a seconda della situazione , se la variabile membro può anche essere statica , puoi semplicemente accedervi nel modo seguente.

class OuterClass
{
    private static int memberVar;

    class NestedClass 
    {
        void SomeFunction() { OuterClass.memberVar = 42; }
    }
}

Sidenote: ho contrassegnato memberVar mirato (e ridondante) come private per illustrare la capacità data dalla classe nidificata di accedere ai membri privati ​​della sua classe esterna.

Attenzione / Si prega di prendere in considerazione

In alcune situazioni questo potrebbe essere il modo più semplice / soluzione alternativa per ottenere l'accesso, ma ...

  • Statico significa anche che la variabile sarà condivisa tra tutti gli oggetti di istanza, con tutti i lati negativi / le conseguenze che ci sono (thread-safety, ecc.)

  • Statico significa anche che questo ovviamente non funzionerà se si ha più di una istanza della classe del genitore e la variabile dovrebbe contenere un valore individuale per ogni istanza

Quindi nella maggior parte dei casi potresti voler seguire un approccio diverso ...

Passare un riferimento

Come la maggior parte delle persone ha suggerito (e poiché è anche la risposta più corretta), ecco un esempio di passaggio di un riferimento all'istanza della classe esterna.

class OuterClass
{
    private int memberVar;
    private NestedClass n;

    OuterClass()   { n = new NestedClass(this); }


    class NestedClass
    {
        private OuterClass parent;

        NestedClass(OuterClass p) { parent = p; }
        SomeFunction() { parent.memberVar = 42; }
    }
}

Answer #5

Un altro metodo, utile in determinate circostanze, consiste nel derivare la classe nidificata dalla classe esterna. Così:

class Outer()
{
    protected int outerVar;
    class Nested() : Outer
    {
        //can access outerVar here, without the need for a 
        // reference variable (or the associated dot notation).
    }
}

Ho usato questa tecnica specialmente nel contesto dei test di unità strutturate . (Questo potrebbe non essere applicabile alla particolare domanda dell'OP, ma può essere utile con le classi annidate in generale, come nel caso di questa domanda "duplicata": " Posso accedere a oggetti di classe esterni nella classe interna ")


Answer #6

invia la master class come parametro di costruzione alla classe nidificata (interna).





inner-classes