What's the best way of accessing field in the enclosing class from the nested class?

Viewed 49119

Say if I have a dropdown in a form and I have another nested class inside of this class . Now what's the best way to access this dropdown from the nested class?

9 Answers

Unlike Java, a nested class isn't a special "inner class" so you'd need to pass a reference. Raymond Chen has an example describing the differences here : C# nested classes are like C++ nested classes, not Java inner classes.

Here is an example where the constructor of the nested class is passed the instance of the outer class for later reference.

// C#
class OuterClass 
{
    string s;
    // ...
    class InnerClass 
    {
       OuterClass o_;
       public InnerClass(OuterClass o) { o_ = o; }
       public string GetOuterString() { return o_.s; }
    }
    void SomeFunction() {
        InnerClass i = new InnerClass(this);
        i.GetOuterString();
    }

}

Note that the InnerClass can access the "s" of the OuterClass, I didn't modify Raymond's code (as I linked to above), so remember that the "string s;" is private because no other access permission was specified.

Nested types aren't like inner classes in Java - there's no inherent instance of the containing type. (They're more like static nested classes in Java.) They're effectively separate classes, with two distinctions:

  • If the containing type is generic, the nested type is effectively parameterised by the containing type, e.g. Outer<int>.Nested isn't the same as Outer<string>.Nested.
  • Nested types have access to private members in the containing type.

Unlike Java, in C# there is no implicit reference to an instance of the enclosing class.

You need to pass such a reference to the nested class. A typical way to do this is through the nested class's constructor.

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";
        }
    }
}

You could pass the enclosing class as a parameter to the nested class constructor, like this:

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

Nested classes are generally not recommended and should be private and/or internal. They are, in my opinion, useful sometimes though.

Correct me if I am wrong, you are trying to process the outer control from inner class hence you ran into this. A better way of doing this would be to handle affairs in a event driven fashion. Use an Observer pattern, Register a listener on the outer control (your nested/inner class will be the listener). Makes life simpler. I am afraid that this is not the answer you were expecting!

there is a good answer above but I like to write sth.

c# nested class is by default private

private to containing class if your want to use it must be public

Related