#820 – A Protected Constructor Allows a Subclass to Create Instances

You can declare a constructor as private to prevent client code from directly instantiating an object.  But then you can no longer subclass the class, because the derived class won’t have access to the constructor.

If you want private constructor semantics, but still be able to create a subclass, you can make a constructor protected.  Other code won’t be able to construct instances of the base class, but your subclass will be able to call the constructor.

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

        protected Dog()
        {
            Console.WriteLine("Constructing Dog");
        }
    }

 

    public class Terrier : Dog
    {
        public double FeistyFactor { get; set; }

        // Implicitly invokes default constructor in base class
        public Terrier(string name, int age, double feistyFactor)
        {
            Console.WriteLine("Constructing Terrier");
            Name = name;
            Age = age;
            FeistyFactor = feistyFactor;
        }
    }

820-001

Advertisement

#716 – How Derived Classes Can Access Protected Members

Marking a class member as protected indicates that the member can be used from code within that class or from code in a derived class.

The derived class, however, can only access a protected member through an instance of the derived class or one of its own subclasses.

In the example below, SecretName is defined in Dog as protected.  It can be accessed in the Terrier subclass only through a Terrier instance, not a Dog instance.

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

        public Dog(string name, string secretName)
        {
            Name = name;
            SecretName = secretName;
        }
    }

    public class Terrier : Dog
    {
        public Terrier(string name, string secretName) : base(name, secretName)
        {
        }

        public void GatherIntel(Dog d, Terrier t)
        {
            // Ok
            Console.WriteLine(string.Format("Dog:{0}, Terrier:{1}", d.Name, t.Name));

            // Ok
            Console.WriteLine(string.Format("Me:{0}, Him:{1}", this.SecretName, t.SecretName));

            // Compiler error
            Console.WriteLine(string.Format("Dog is {0}", d.SecretName));
        }
    }

#309 – Accessing Protected Members In a Derived Class

A member of a class with its accessibility set to protected is accessible from within the class that defines the member and from within classes that derive from the defining class.

You’d typically access protected instance members through the this reference in the defined class.

    public class Dog
    {
        protected string locationOfBone;
    }

    public class Terrier : Dog
    {
        public void DivulgeTerrierSecrets()
        {
            // CAN access protected member through implicit this reference
            Console.WriteLine("Bone is: {0}", locationOfBone);
        }
    }

However, when the subclass is accessing the protected member, it must do so through an instance of the subclass and not through an instance of the parent class.

    public class Terrier : Dog
    {
        public static FindSecret()
        {
            Terrier t = new Terrier("Jack");
            string s = t.locationOfBone;   // OK

            Dog d = new Dog("Spot");
            string s = d.locationOfBone;   // Not OK - ERROR
        }
    }

#308 – Protected Internal Class Members

Class members marked with the accessibility keyword protected internal are accessible from within the same class, from within code in classes that derive from the class, or from within code in classes within the same assembly.

In the picture below, the Dog.DoBark method is marked as protected internal.  The code in any of the blue blocks can call this method.

#306 – Protected Class Members

Class members marked with the accessibility keyword protected are accessible from within the same class, or from within the code of any classes that derive from the class.

In the picture below, the Dog.DoBark method is marked as protected.  The code in any of the blue blocks can call this method.

Code in a subclass of Dog can call the DoBark method.

    public class Terrier : Dog
    {
        public void TerrierBark()
        {
            // CAN call DoBark from subclass
            this.DoBark();
        }
    }

Code in other classes, not derived from Dog, cannot call the DoBark method.

    public class OtherClass
    {
        public void DoSomething()
        {
            Dog d = new Dog();
            // This class CANNOT call DoBark()
            d.DoBark();
        }
    }

#303 – Accessibility of Class Members

Members of a class can have different kinds of accessibility.  An accessibility keyword indicates what source code can access the member.  The different types of accessibility are:

Accessibility Keyword Description
public All code can access the member
private Only other code in the class can access the member
protected Code in this class or any class that inherits from this class can access
internal Code in files in the same assembly (.dll or .exe) can access
protected internal Code in the same assembly or in classes that inherit from this class can access

Accessibility keywords can apply to the following kinds of members of a class: fields, properties, methods, constants, indexers, events, constructors and nested types.  They can apply to both instance and static members.