#629 – Nested Types Have Full Access to Members in Parent

When you declare a nested type, the inner type has access to everything in the parent type, even if the items in the parent are declared as private or protected.

    public class Dog
    {
        public string Name { get; set; }

        private string secretName;
        private DogCollar collar;

        public Dog(string name)
        {
            Name = name;
            secretName = "Calypso";
            collar = new DogCollar(this);
        }

        private class DogCollar
        {
            public DogCollar(Dog belongsTo)
            {
                // We can see secretName even though it is private
                Console.WriteLine(string.Format("Secret name is {0}", belongsTo.secretName));
            }
        }
    }


Note that the nested type does not automatically inherit a reference to a particular instance of the parent class. We need to pass this information into the nested type.

Advertisement

#628 – Why You Might Create a Nested Type

The most common reasons for creating a nested type–one type defined within another one–are:

  • For information hiding purposes, so only the outer type has access to the type being defined
  • As a way of organizing your code, associating a sub-type with the parent type where it is used

One scenario might be that you define several subclasses inside of a parent class and make the subclasses private.  You might also use the parent class as a factory, returning instances of the subclass (but visible to client through the parent class’ type).  Doing this guarantees that no code outside of the parent class can directly work with the subclasses, but has to go through the parent class to instantiate them.

#627 – Accessibility of Nested Types in a struct or a class

When you define a type within the scope of a class (a nested type), the accessibility of the nested type can be one of the following

  • public
  • protected internal
  • protected
  • internal
  • private  (default)

When you define a type within a struct, the choices for accessibility of the nested type are more limited and include:

  • public
  • internal
  • private  (default)

Remember that the outer type (the class or struct) has more limited accessibility choices:

  • public
  • internal  (default)

#625 – Reference a Nested Type Using Dot Notation

If a nested type is declared with the proper access modifier, it will be accessible from outside the class that contains it.  To use a nested type, you use a dot notation that looks like the following:

OuterType.InnerType

For example, let’s say that you define a DogCollar class inside the definition of a Dog class.  If DogCollar is made accessible from outside the implementation of Dog, you could use it as follows:

            Dog.DogCollar jacksCollar = new Dog.DogCollar(6);

Note that, unlike namespaces, you cannot include a using statement that would allow you to use the DogCollar type name without the Dog prefix.  The nested type must always be prefixed by the name of the containing type.

#623 – Defining One Type Inside Another Type

You can define one type within the scope of  another one.  This is known as nesting.  The inner type can have a different accessibility level than the outer type, so it may or may not be visible from outside the outer type.

For example, we might define a DogCollar class within the Dog class.

We’ve made the DogCollar class private, which means that only code within the Dog class can use the DogCollar class.  Code outside of Dog will not be able to make use of the DogCollar type.

    public class Dog
    {
        public string Name { get; set; }
        private DogCollar myCollar;

        public Dog(string name, int collarLength)
        {
            Name = name;
            myCollar = new DogCollar(collarLength);
        }

        private class DogCollar
        {
            public int Length { get; set; }
            public DogCollar(int len)
            {
                Length = len;
            }
        }
    }