Access Specifiers in C#

Introduction

Access Specifiers are the keywords that specify accessibility of the object. In other words, access Specifiers define the scope of the user-defined type and its members, i.e. we define who can access the class and its members.

As this topic needs at least some basic understanding about object-oriented concepts, so before going through this post you must visit the object-oriented concepts

C# provides us with 5 types of access specifiers:

  1. private
  2. public
  3. internal
  4. protected
  5. protected internal

So when we declare the members in a class with any of the access specifiers, that members will be accessible within the class boundaries. The restrictions start when we move out of the class. We will check each individual access specifier and its functionality.

private

private access specifiers’ scope is only limited to the class or struct in which they are declared. The private members cannot be accessed outside the class if you are trying to access the private member outside the class then will get a compile-time error. Private access specifiers are the least permissive access level.

Note: private is default access specifier that means when we don’t specify any access specifier then by default its private

Example:

using System;

namespace Applications
{
    class PrivateAccess
    {
        private string str = "This variable is private ";
        private void Print(string str)
        {
            Console.WriteLine("This function is private : " + str);
        }
    }
    class Program
    {
        static void Main()
        {
            PrivateAccess privateAccess = new PrivateAccess();
            privateAccess.Print("Program Class");
            Console.WriteLine(privateAccess.str);
        }
    }
}

In above example we are trying to access private member of “PrivateAccess” class from another class “program”, so we are getting compile time error. If you notice class “PrivateAccess” can access its private member of same class, we can see private method ”print” can access private variable “str” because they both are defined inside same class. So we will get below error in above program

‘PrivateAccess.Print(string)’ is inaccessible due to its protection level
‘PrivateAccess.str’ is inaccessible due to its protection level

public

The scope of public access specifiers is not limited to the class or struct. It can be accessible from anywhere. So the scope of the accessibility is inside the class as well as outside of the class. Public access specifiers can be accessed from the same assembly or another assembly that reference it

using System;

namespace Applications
{
    class PublicAccess
    {
        public string str = "This variable is private ";
        public void Print(string str)
        {
            Console.WriteLine("This function is private : " + str);
        }
    }
    class Program
    {
        static void Main()
        {
            PublicAccess _access = new PublicAccess ();
            _access.Print("Program Class");
            Console.WriteLine(_access.str);
        }
    }
}

As you can see in the above example, we can access all the members from another class because in class “PublicAccess” it’s defined as public.

internal

Some time we need to class and data members should be accessible through the assembly (typically when you create a project in visual studio, each project is referred to as one assembly). The internal access modifiers can allow accessibility of class and members within the same assembly but not from another assembly.


using System;

namespace Applications
{
    class InternalAccess
    {
        internal string str = "This variable is private ";
        internal void Print(string str)
        {
            Console.WriteLine("This function is private : " + str);
        }
    }
    class Program
    {
        static void Main()
        {
            InternalAccess access = new InternalAccess();
            access.Print("Program Class");
            Console.WriteLine(access.str);
        }
    }
}

protected

The protected access specifier defines the scope of accessibility of a class and the member is limited within the class or struct and the class derived (Inherited) from this class.

In other words, protected type or member which is declared in parent class becomes accessible in inherited child class and in the same parent class only. (There is no limitation of assembly)


using System;
using System.CodeDom;

namespace Applications
{
    public class ProtectedAccess
    {
        protected string str = "This variable is private ";
        protected void Print(string str)
        {
            Console.WriteLine("This function is private : " + str);
        }
    }
    class Program
    {
        static void Main()
        {
            ProtectedAccess access = new ProtectedAccess();
            access.Print("Program Class");
            Console.WriteLine(access.str);
        }
    }

    class ProtectedAccessChild : ProtectedAccess
    {
        public void Test()
        {
            Print("Program Class");
            Console.WriteLine(str);
        }
    }
}

In above example we can see that program class will generate a below errors
‘ProtectedAccess.Print(string)’ is inaccessible due to its protection level

Whereas “ProtectedAccessChild” class can able to access class “ProtectedAccess”.

protected internal

Protected internal is the combination of protected and internal access specifiers. Protected allows variable access only from inherited class and internal allow to access from the entire assembly.

using System;
using System.CodeDom;

namespace Applications
{
    public class ProtectedInternalAccess
    {
        protected internal string str = "This variable is private ";
        protected internal  void Print(string str)
        {
            Console.WriteLine("This function is private : " + str);
        }
    }
    class Program
    {
        static void Main()
        {
            ProtectedInternalAccess internalAccess = new ProtectedInternalAccess();
            internalAccess.Print("Program Class");
            Console.WriteLine(internalAccess.str);
        }
    }

    class ProtectedInternalAccessChild : ProtectedInternalAccess
    {
        public void Test()
        {
            Print("Program Class");
            Console.WriteLine(str);
        }
    }
}

Examples

In the above example, we can see the class which inheriting also access members of “ProtectedInternalAccess” and “program” class also access the same member without inheriting the class.

Lets understand all access specifiers using one example lets create a separate class library project “TestClassLib”

using System;

namespace TestClassLib
{
    public class TestSpecifiers 
    {
        public void PublicPrint()
        {
            Console.WriteLine("Public Method of  TestClassLib");
        }

        public void PrivatePrint()
        {
            Console.WriteLine("Private Method of  TestClassLib");
        }

        internal void InternalPrint()
        {
            Console.WriteLine("internal   Method of  TestClassLib");
        }

        protected void ProtectedPrint()
        {
            Console.WriteLine("protected  Method of  TestClassLib");
        }

        protected internal void ProtectedInternalPrint()
        {
            Console.WriteLine("protected internal   Method of  TestClassLib");
        }
    }
}

Accessing the members of a class from same class.

Let’s add method to the same class to access the members of a class from same class

using System;

namespace TestClassLib
{
    public class TestSpecifiers 
    {
        public void PublicPrint()
        {
            Console.WriteLine("Public Method of  TestClassLib");
        }

        public void PrivatePrint()
        {
            Console.WriteLine("Private Method of  TestClassLib");
        }

        internal void InternalPrint()
        {
            Console.WriteLine("internal   Method of  TestClassLib");
        }

        protected void ProtectedPrint()
        {
            Console.WriteLine("protected  Method of  TestClassLib");
        }

        protected internal void ProtectedInternalPrint()
        {
            Console.WriteLine("protected internal   Method of  TestClassLib");
        }


        public void Test()
        {
            PrivatePrint();
            PublicPrint();
            InternalPrint();
            ProtectedPrint();
            ProtectedInternalPrint();
        }
    }
}

You can see we are able to access all the members from the same class and there is no restriction on Accessing the members of a class from same class.

Accessing the members of a class from another class of same assembly.

Lets create a another class in the same project and will try to access the method of a class “TestClassLib”

namespace TestClassLib
{
    class InvokeTestSpecifiers
    {
        public void Invoke()
        {
            TestSpecifiers testSpecifiers = new TestSpecifiers();
            testSpecifiers.ProtectedInternalPrint();
            testSpecifiers.PublicPrint();
            testSpecifiers.InternalPrint();
        }
    }
}

Visual studio IntelliSense

access specifier in c#, access specifier in oop,  private and public access modifiers in C#, protected access specifier in C#, protected internal access specifier, explain protected internal access specifier, example of access specifier

In above example you can see that we can only access public, internal and protected internal methods from another class.

Accessing the members of a class from child class of same assembly.

Lets inherit “InvokeTestSpecifiers” class from “TestClassLib” and we will try to access the members

namespace TestClassLib
{
    class InvokeTestSpecifiers : TestSpecifiers
    {
        public void Invoke()
        {
            ProtectedInternalPrint();
            ProtectedPrint();
            PublicPrint();
            InternalPrint();
        }
    }
}

Visual studio IntelliSense

access specifier in c#, access specifier in oop,  private and public access modifiers in C#, protected access specifier in C#, protected internal access specifier, explain protected internal access specifier, example of access specifier

As we can see C# allow to access public, protected, internal, protected internal methods in child class.

Accessing the members of a class from another class of different assembly.

So lets add new project and add reference of this project to a newly added project to access the class “TestClassLib”


using System;
using TestClassLib;

namespace Applications
{
    class Program
    {
        static void Main()
        {
            TestSpecifiers testSpecifiers = new TestSpecifiers();
            testSpecifiers.PublicPrint();
        }
    }
}

Visual studio IntelliSense

access specifier in c#, access specifier in oop,  private and public access modifiers in C#, protected access specifier in C#, protected internal access specifier, explain protected internal access specifier, example of access specifier

We can see from another assembly it is only allow public method to access it.

Accessing the members of a class from child class of differant assembly.

Let’s inherit the “Program” class from “TestClassLib” class

using System;
using TestClassLib;

namespace Applications
{
    class Program : TestSpecifiers
    {
        static void Main()
        {
            Console.WriteLine("Print");
        }

        void Test()
        {
            PublicPrint();
            ProtectedPrint();
            ProtectedInternalPrint();
        }
    }  
}

Visual studio IntelliSense

access specifier in c#, access specifier in oop,  private and public access modifiers in C#, protected access specifier in C#, protected internal access specifier, explain protected internal access specifier, example of access specifier

As you can see it only allow to access public, protected and protected internal from the class.

Hope this will clear all doubt related with Access specifiers. Please add comments or question if you have any.


Leave a Reply

Your email address will not be published. Required fields are marked *