Access Modifiers in C#

In this post, we’ll go through the different types of access modifiers and how to utilize them in C#.

Access Modifiers in C#
Access Modifiers in C#

In C#, access modifiers are keywords that describe how a class, its properties, fields, or methods are accessible in a program. These access modifiers are mainly used to specify the type’s and its members’ scopes, as well as to safeguard data from being accidentally changed by external classes or programs.

What are the types of access modifiers in C#?

The following six types of access specifiers are available in C#.

    • public
    • protected
    • internal
    • protected internal
    • private
    • private protected

Access Modifiers Summary Table

With the help of the Diagram below, you can easily understand all the access modifiers.

C#-Access Modifiers diagram
C#-Access Modifiers diagram

Public Access Modifier In C#

The public keyword makes classes (including nested classes), properties, methods, or fields accessible from anywhere, both inside and outside of the program assembly.

Accessibility

    • A type or member declared as public can be accessed by any other code in the same assembly or another assembly that references it.
    • All classes can access the code.
    • Public members can be accessed from any part of the code. As a result, they are the least safe. Any code logic can change the value, resulting in unanticipated behaviour. As a result, extreme caution must be exercised before making any object public.

Example Of Public Access Modifier

The following examples demonstrate how to specify public access modifiers on a type and member.

using System;

namespace publicAccessModifierExample
{
    // public access modifier example

    public class Person
    {
        // Declaring member name as public
        public string name = "Shekh Ali";
    }

    class Program
    {
        static void Main(string[] args)
        {
            // Creating object of the class Person
            Person person = new Person();

            // Displaying name of the person
            Console.WriteLine($"Name: {person.name}");
            Console.WriteLine();
        }
    }

}
// Output:
// Name: Shekh Ali

In the above program, the name variable implements the public access modifier and can be accessed from anywhere in the project. Therefore, there are no accessibility restrictions.

Protected Access Modifier In C#

The protected access modifier indicates that the members can be accessed in both the containing class and derived classes.

Accessibility

    • Protected members are only visible to their own classes and their derived classes.
    • Protected members cann’t be accessed by the object of the class.

Example Of Protected Access Modifier

The following examples demonstrate how to specify protected access modifiers on a type member.

using System;
namespace protectedAccessModifierExample
{
    class BaseClass
    { 
       // protected variable
       protected int number; 
       // constructor
       public BaseClass()
        {
            // protected variable can be accessed inside this 'BaseClass' class
            number = 50;
        }
    }
    // 'DerivedClass' inherits the 'BaseClass'
    class DerivedClass : BaseClass 
    {
        // Members of class 'DerivedClass' can access 'number'
        public void Display()
        {         
            // we can access 'number' in this class as well
            // because it derives from the NumberClass class
            Console.WriteLine($"number = {number}"); 
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // Creating instance of the base class
            BaseClass baseClass = new BaseClass();

          // Error. The 'BaseClass.number' variable is inaccessible due to its protection level. 
            // The Program class doesn't derive from the NumberClass
            // Console.WriteLine(baseClass.number); 

            // Creating instance of the derived class
            DerivedClass derivedClass = new DerivedClass();
            // Displaying the value of 'number'
            derivedClass.Display();

            Console.WriteLine();           
        }
    }
}
// Output:
// number = 50

In the above code, the class ‘DerivedClass’ inherits from ‘BaseClass’, therefore, any protected members of ‘BaseClass’ can be accessed from ‘DerivedClass’.

Internal Access Modifier In C#

In C#, the internal access modifier specifies that the type or members declared as internal can only be accessed in its own assembly, but not in other assemblies.

    • Internal access modifier is commonly used in component-based development because it allows a set of components to work together in a private manner without exposing to the rest of the application code.
    • Access is limited to the current assembly.

Example – Internal access modifier

This example contains two files in two separate projects, Assembly1.cs and Assembly2.cs. The first file contains an internal base class BaseClass. In the second file, an attempt to instantiate BaseClass will fail.

Assembly1.cs

namespace Assembly1
{ 
    // Assembly1.cs
    internal class BaseClass
    {
        internal static int number = 50;
    }
}

Assembly2.cs

using Assembly1;
namespace Assembly2
{
    // Assembly2.cs
    class Program
    {
        static void Main(string[] args)
        {
            //  instantiate BaseClass
            BaseClass baseClass = new BaseClass();  
            // error: Base class is inaccessible due to its protection level                        
        }
    }
}

internal access modifier in C#
image-internal access modifier in C#

Protected Internal Access Modifier In C#

The protected internal access modifier in C# is a combination of the protected and internal access modifiers. Therefore, protected internal types or members can only be accessed inside the same assembly or through derived classes in other assemblies.

Consider the following code snippet as an example:

Example- Protected Internal Access Modifier

Assembly1.cs

using System;

namespace Assembly1
{ 
    // Assembly1.cs
    public class BaseClass
    { 
        // Declare protected internal member
        protected internal int number = 50;
    }
    class TestAccessInSameAssembly
    {
        void Access()
        {
            BaseClass baseObject = new BaseClass();
            // Accessible in the same assembly
            Console.WriteLine(baseObject.number);
        }
    }
}

Assembly2.cs

using Assembly1; // referencing the first assembly
using System;
namespace Assembly2
{
    // Assembly2.cs
    class Program : BaseClass
    {
        static void Main(string[] args)
        {
            //  instantiate BaseClass
            BaseClass baseClass = new BaseClass();
            //baseClass.number;
            // Error CS1540, because 'number' can only be accessed by
            // classes derived from BaseClass.

            // Creating instance of the derived class
            Program program = new Program();
            // 'number' is accessible in the derived class
            Console.WriteLine($"number = {program.number}");

        }
    }
}

protected internal access modifier output
image-protected internal access modifier output

Private Access Modifier In C#

The members having the private access modifier, such as variables and methods, are only accessible within the body of the class or struct in which they are declared.

Accessibility

    • The private keyword is just a member access modifier and cannot be explicitly used by classes or structures.
    • Nested types in the same body can also access these private members.
    • When a private member is referenced outside of the class or structure in which it is declared, a compile-time error will be thrown.

Example- Private Access Modifier

Let’s take an example and see what happens when we use the private access modifier.

using System;
namespace PrivateAccessModifier
{ 
    class PrivateClass
    {  // private variable
        private int number = 50;

        public double PrintNumber
        {  
            // private members are accessible inside the same class
            get { return number; }
        }

    }    
    class Program 
    {
        static void Main(string[] args)
        {
            PrivateClass privateClass = new PrivateClass();

            // Compile Error - 'privateClass.number' is inaccessible due to its protection level
            // Console.WriteLine($"number = {privateClass.number}");

            // 'number' is indirectly accessed via public property
            Console.WriteLine($"number = {privateClass.PrintNumber}");
        }
    }
}

Private Protected Access Modifier In C#

The private protected modifier is available in C# version 7.2 and later. It’s used to specify that the containing class and its derived types in the current assembly can only access private protected members.

    • When we wish to restrict object access even in derived classes in other assemblies, we can use the private protected modifier.
    • The members of the struct cannot be private protected, because the structure cannot be inherited.

Example – Private Protected Access Modifier

Consider the following code snippet as an example:

using System;
namespace PrivateProtectedAccessModifier
{
    class BaseClass
    {
        // private protected member
        private protected int number = 50;

        // number is Accessible only inside the current class 
        // in the current assembly
        public int getNumber()
        {
            return number;
        }

    }
    class DerivedClass : BaseClass
    {
       
        static void Main(string[] args)
        {
            BaseClass baseClass = new BaseClass();
            // baseClass.number = 10;
            // Compile-time Error CS1540, because 'number' can only be accessed by
            // classes derived from BaseClass.
         

            // OK, accessed value of 'number' through the current derived class instance
            DerivedClass derivedClass = new DerivedClass();       
            Console.WriteLine($"number = {derivedClass.number}");
        }
    }
}

// Output:
// number = 50

Learn more on MSDN

Conclusion

I hope you found this post useful in learning about access modifiers in C#. Your comments, suggestions, and constructive criticism are much appreciated.

Recommended Articles

    1. 10 Difference between interface and abstract class In C#
    2. Exception Handling in C#| Use of try, catch and finally block
    3. C# Enum | How To Play With Enum in C#?
    4. C# extension methods with examples
    5. Properties In C# with examples
    6. Generic Delegates in C# With Examples
    7. Constructors in C# with Examples
    8. C# Dictionary with Examples
    9. Multithreading in C#
    10. IEnumerable Interface in C# with examples

Leave a Reply