C # Can not Call Protected Void Method

I have the following code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{
    abstract class parent
    {
        public abstract void printFirstName();

        protected virtual void printLastName()
        {
            Console.WriteLine("Watson");
        }

        protected void printMiddlename()
        {
            Console.WriteLine("Jane");
        }
    }

    class child: parent
    {
        public override void printFirstName()
        {
            Console.WriteLine("Mary");
        }

        protected override void printLastName()
        {
            Console.WriteLine("Parker");
        }

        public void getMiddleName()
        {
            printMiddlename();
        }
    }

    class Program: child
    {
        static void Main(string[] args)
        {
            child ch = new child();

            ch.printFirstName();
            ch.getMiddleName();
            //ch.printLastName();

            Console.Read();
        }
    }
}

This code runs properly and prints Mary Jane

However, when I uncomment ch.printLastName(); it showscompile error:

Why cant my Program Class call protected method of Child Class? especially when The child class has no problem calling the protected method (printMiddleName) of Parent class?


I guess you are confusing inheritance and access levels.

Your Program class inherits the printFirstName method from child. So inside your Program class you can access that method:

class Program : child
{
    void Method() { this.printFirstName(); }
}

From outside a class you cannot access protected methods. But from inside a class you can access the protected methods of instance the same type:

class Program : child
{
    void Method()
    {
        Program p1 = new Program();
        p1.printFirstName(); // this works

        child c1 = new child();
        p1.printFirstName(); // this gives your compiler error
}

But you cannot access a protected method of an instance of a different type, even if it is a type you derived from.

See MSDN about access levels for more details.