C# Access Modifiers: Everything You Need to Know (With Examples)

One of the fundamental features of C# is the use of access modifiers. These modifiers control the accessibility of classes, methods, and variables in your code.

In this article, we will take a comprehensive look at C# access modifiers, exploring their various types, their effects on code, and best practices for using them.

Access Modifiers in C#
C# Access Modifiers

Understanding Access Modifiers in C#

In C#, Six access modifiers are available for use in your code. These modifiers determine the accessibility of classes, methods, and variables to other parts of your code and external code.

These access modifiers are mainly used to define the scopes of types and members and prevent external programs from accidentally changing data.

Types of access modifiers

The following six access modifiers are available in C#.

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

Summary Table

You can quickly understand all of the access modifiers by using the below summary table.

C#-Access Modifiers diagram
C# Access Modifiers summary table.

The following access modifiers are available in C#:

No.C# ModifiersDescription
01.public:The code is accessible from all classes. That means other code in the same assembly or another assembly referencing it can access the type or member.
02.private:The code is only accessible within the same class or struct.
03.protected:The code (type or member) is accessible within the same class or in a class inherited from that class.
04.internal:The code (type or member) can be accessed by any code in the same assembly but not by code from another assembly.
05.protected internal:The class, members, etc., can be accessed by any code in the assembly in which it is declared or by a derived class in another assembly.
06.private protected:The code (type or member) can be accessed by types derived from the class declared within the current assembly. In other words, access is granted to the contained class and its derived types in the current assembly.
C# access modifiers/specifiers

01. Public Access Modifier

The public access modifier allows unrestricted access to the class, method, or variable, including external code, from anywhere in the program. Any code can access the class, method, or variable without restrictions.

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.
  • The public members of a class 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 unexpected behaviour. As a result, extreme caution must be exercised before making any object public.

Example:

The following examples demonstrate how to specify public access modifiers on a class 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.

02. Protected Access Modifier

The protected access modifier allows access to the class, method, or variable from within the class and any derived classes. It means that the class, method, or variable can be accessed by any code that is part of the class or any derived classes but not by external code.

Accessibility:

  • Protected members are only visible to their classes and their derived classes.
  • We can’t access protected members by the object of that class.

Example:

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, we can access any protected members of BaseClass from the DerivedClass object.

03. Internal Access Modifier

The internal access modifier restricts access to the class, method, or variable within the same assembly. An assembly is a compiled output of your code, such as a DLL or EXE file. Any code within the same assembly can access the class, method, or variable, but external code cannot.

Accessibility:

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

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

Example:

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.

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#

04. Protected Internal Access Modifier

The protected internal access modifier combines the functionality of the protected and internal access modifiers. 

It means that any code can access the class, method, or variable within the same assembly or any derived classes, but not by external code that is not part of the same assembly or derived classes.

A 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:

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);
        }
    }
}

Let’s write code in the Assembly2.cs file

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

05. Private Access Modifier

The private access modifier restricts access to the class, method, or variable only within the class in which it is defined. No external code can access the class, method, or variable, making it useful for encapsulation and data hiding.

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.
  • A compile-time error will be thrown when a private member is referenced outside of the class or structure in which it is declared.

Example:

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}");
        }
    }
}

06. 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.
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

Best Practices for Using Access Modifiers in C#

When using access modifiers in your C# code, it’s important to follow some best practices to ensure that your code is maintainable, scalable, and secure.

a. Use the Most Restrictive Access Modifier Possible

When defining a class, method, or variable, you should always use the most restrictive access modifier possible. It means that you should only grant access to code that needs it, and no more.

b. Use Private Access Modifiers for Variables

When defining variables, you should use private access modifiers to encapsulate and hide data. It helps to prevent unintended changes to your data and improves the maintainability of your code.

c. Use Public Access Modifiers for Methods

When defining methods, you should use public access modifiers to allow other parts of your code to access and use them. That makes it easier to reuse code and improves the scalability of your programs.

d. Use Protected Access Modifiers for Inheritance

When defining classes intended for inheritance, you should use protected access modifiers to allow derived classes to access the parent class’s methods and variables. It makes maintaining and updating your code easier as your program grows.

References: MSDN.

FAQs

Q: What level of accessibility do members of an interface have?

Ans: Members of the interface are by default public. You are not permitted to use any explicit access modifiers with interface members.

Q: Is it possible for derived classes to have a higher level of accessibility than their base types?

Ans: No, Derived classes cannot have greater accessibility than their base types. You are not allowed to declare a public class B that derives from an internal class A.

Q: Is it possible to make struct members as protected in C#?

Ans: No, struct members cannot be declared as protected. This is because the structure does not support inheritance.

Q: What is the default access modifier for a class, struct, or interface declared within a namespace?

Ans: Internal is the default access modifier for class, struct, and interface.

Q: What is the default access modifier for class members?

Ans: If we do not specify an access modifier, all class members are private by default.

Q: Why is the access modifier not allowed in namespaces?

Ans: Namespaces do not support access modifiers because they do not have access restrictions.

Q: What is the importance of access modifiers in C#?

Ans: Access modifiers prevent unauthorized data alteration by other classes or programs.

References: MSDN- C# Access Modifiers, W3Schools- access modifiers in c#

Recommended Articles:

I hope this post helped you learn more about “access modifiers in C#”. If you like this post, please share it with others. I welcome your comments, suggestions, and constructive criticism. Thanks.

Shekh Ali
4 1 vote
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments