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

C#.NetInner Classes

C# Problem Overview


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?

C# Solutions


Solution 1 - C#

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.

Solution 2 - C#

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.

Solution 3 - C#

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

Solution 4 - C#

Static Members

Since no one has mentioned it so far: Depending on your situation, if the member variable can also be static, you could simply access it in following way.

class OuterClass
{
    private static int memberVar;

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

Sidenote: I marked memberVar purposefully (and redundantly) as private to illustrate the given ability of the nested class to access private members of it's outer class.

Caution / Please consider

In some situations this might be the easiest way/workaround to get access, but ...

  • Static also means, that the variable will be shared across all instance objects, with all the downsides/consequences there are (thread-safety, etc.)

  • Static also means, that this will obviously not work if you have more than one instance of the parent's class and the variable should hold an individual value for each instance

So in most cases you might wanna go with a different approach ...

Passing a Reference

As most people have suggested (and because it is also the most correct answer), here an example of passing a reference to the outer class' instance.

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

Solution 5 - C#

One other method, which is useful under certain circumstances, is to derive the nested class off of the outer class. Like so:

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

I have used this technique especially in the context of Structured Unit Tests. (This may not apply to the OP's particular question, but it can be helpful with nested classes in general, as in the case of this "duplicate" question: " https://stackoverflow.com/questions/2957900/can-i-access-outer-class-objects-in-inner-class ")

Solution 6 - C#

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.

Solution 7 - C#

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!

Solution 8 - C#

send the master class as an constructor parameter to the nested (inner) class.

Solution 9 - C#

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLearnerView Question on Stackoverflow
Solution 1 - C#Ray HayesView Answer on Stackoverflow
Solution 2 - C#Jon SkeetView Answer on Stackoverflow
Solution 3 - C#Jason KresowatyView Answer on Stackoverflow
Solution 4 - C#LeviteView Answer on Stackoverflow
Solution 5 - C#kmoteView Answer on Stackoverflow
Solution 6 - C#mannuView Answer on Stackoverflow
Solution 7 - C#questzenView Answer on Stackoverflow
Solution 8 - C#Hamid JolanyView Answer on Stackoverflow
Solution 9 - C#afshar003View Answer on Stackoverflow