2

In C#, why does a nested class have to instantiate it's parent class, to reference its parent class non-static properties in code?

public class OuterClass
{
    public int OuterClassProperty
    {
        get
        {
            return 1;
        }
    }

    public class InnerClass
    {
        public int InnerClassProperty
        {
            get
            {
                /* syntax error: cannot access a non-static
                 * member of outer type via nested type.
                 */
                return OuterClassProperty;
            }
        }
    }
}

It seems I have to do this instead:

public class OuterClass
{
    public int OuterClassProperty
    {
        get
        {
            return 1;
        }
    }

    public class InnerClass
    {
        public int InnerClassProperty
        {
            get
            {
                OuterClass ImplementedOuterClass = new OuterClass();
                return ImplementedOuterClass.OuterClassProperty;
            }
        }
    }
}

I'm thinking the first code example should be okay, because if InnerClass is instantiated, the parent class would implemented first - along with the parent class properties.

Thanks for the help, I'm trying to learn the in's and out's of C#... and I am not familiar with Java, comparing to Java won't help much...

Aaron Thomas
  • 5,054
  • 8
  • 43
  • 89
  • 4
    `new InnerClass()` doesn't instantiate (implicitly or otherwise) `OuterClass`. And the property you're referencing is an instance property. – Brad Christie Apr 24 '15 at 18:05
  • @GrantWinney you are correct, I've edited. – Aaron Thomas Apr 24 '15 at 18:06
  • 1
    You don't need to "instantiate" the outerclass to get the inner class, you could do : var x = new OuterClass.InnerClass(); and it would not create an instance of the outer class. – Ron Beyer Apr 24 '15 at 18:08
  • 1
    There is a good chance you are coming form Java background where inner classes behave differently, even if not I believe http://stackoverflow.com/questions/2367015/java-inner-classes-in-c-sharp answers your question. – Alexei Levenkov Apr 24 '15 at 18:09
  • 1
    From a beginner's perspective, this question may be helpful: http://stackoverflow.com/questions/1083032/why-would-i-ever-need-to-use-c-sharp-nested-classes – Brad Christie Apr 24 '15 at 18:09
  • 2
    Unlike Java, in C# nested classes are not functionally different from namespace-level classes. They are instantiated on their own. The difference is only in name scope and visibility. – ach Apr 24 '15 at 18:10
  • @RonBeyer amazing I didn't realize that was even possible. But that explains a lot... anyone care to leave an answer, I'll mark as answered. – Aaron Thomas Apr 24 '15 at 18:15
  • @AlexeiLevenkov unfortuantely I'm not coming from a java background - this is not a duplicate. Looking at what you've linked doesn't answer my question, but compares C# to Java, without answering my question. – Aaron Thomas Apr 24 '15 at 18:18
  • The linked dupe really does answer the question (although it does it by comparison to Java). There is nothing automatically inferred or special about an inner class. As @AndreyChernyakhovskiy, the only difference are in scope and visibility. You don't automatically get a reference to any instance of the outer class. But if the outer class has a property that always returns `1`, as in your example, it should probably be static and could then be accessed the same as any other static property without needing an instance of the class. – Matt Burland Apr 24 '15 at 18:26
  • @MattBurland thank you for clarification. I still disagree for two reasons (1) answering a language-specific question with another question that compares two language doesn't seem right. perhaps an answer that explained in such a way that comparing to another language to clarify would be better? (2) this post was marked as duplicate, preventing answers, so now we are forced to the answer in the comments http://meta.stackoverflow.com/q/253045/2658159. By the way, how to accomplish this with static classes is outside the scope of this question, that's why I made the first sentence the way it is. – Aaron Thomas Apr 24 '15 at 18:48
  • As I look more into this, I found MSDN documentation reads "To access the containing type, pass it as a constructor to the nested type." https://msdn.microsoft.com/en-us/library/ms173120.aspx – Aaron Thomas Apr 24 '15 at 19:06
  • @AaronThomas: If it's not static, then what you are trying to do really doesn't make any sense. If it's always the same value in the outer class, regardless of *which instance* you are looking at, then it should be `const`. If it's different for different instances of the outer class, then how do you suppose an instance of the inner class is going to know which instance of the outer class created it? You are expecting inner classes to do something that they don't (but may do in other languages, like Java). – Matt Burland Apr 24 '15 at 19:22
  • @AaronThomas I've reopened question and provided answer. Completely useless from my point of view, but I believe it answers your *exact* question as it is asked. Hopefully someone from C# design team will see this question and provide you historical background that this question seem to be seeking for. – Alexei Levenkov Apr 24 '15 at 20:28

1 Answers1

5

The behavior you are observing is explicitly spelled out in the C# specification. Snippet of C# 5.0 below:

10.3.8.4 this access
A nested type and its containing type do not have a special relationship with regard to this-access (§7.6.7). Specifically, this within a nested type cannot be used to refer to instance members of the containing type. In cases where a nested type needs access to the instance members of its containing type, access can be provided by providing the this for the instance of the containing type as a constructor argument for the nested type.

The behavior of nested classes in C# is different for other language like Java inner classes in c# and C+ because C# is different language created by different language design team. Exact historical reasons why particular behavior was selected possibly could be found in blogs of members of C# design team, .Net design guidelines book or MSDN articles.

Community
  • 1
  • 1
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179