In this article I am going to discuss about C# access specifiers in detail but before that if you had not read my previous article of C# access modifiers then must read it for better understanding. In this article we learn about what is access specifiers, what are the different-2 types of specifiers and what are the access levels of all access specifiers.

What is C# Access Specifiers?

In C#, Access specifiers are used to used to define the scope of class, interface, function, constructor, enums, structs and and its members. Here scope means accessiblity that who can access these things. C# access specifiers are also known as access modifiers because every keyword that we use in our programs like virtual, sealed, partial, abstract, static, base etc are modifiers and because access specifiers also contains some keywords so that it is also known as access modifiers.

Types of C# Access Specifiers

These are 7 types of access specifiers in csharp programming but mostly used access specifiers are public, private, internal and protected.

csharp-access-specifiers

Accessibility (Scope) of Access Specifiers

Before using the access specifiers you must have to know about the scope (accessibility) of each and every modifier. So that you must clear about the use case of each access specifiers. To understand each and every modifier accessibility you can take the reference of given picture that is taken from the official documentation of microsoft that explains the scope of each access specifier in very good way.

csharp access specifers scopes

Now lets understand each and every access specifier with an example.

1. C# Public Access Specifier

When we declare a type with public access specifier then that means there is no restriction and it is accessible from anywhere. Here type means classes, structs, enums, interfaces, and delegates and variables, properties, constructors, methods are called type members. We can also use the classes of other files using their namespace it is public otherwise we got a error. Let see an example to know about public access specifier.

using System;

public class Car
{
  public string carName = "Mustang";
}


public class HelloWorld
{
    public static void Main(string[] args)
    {
        Car obj = new Car();
        Console.WriteLine(obj.carName);
    }
}
Output:
Mustang

you can see in above code that we can access the carName in another class because the access specifier is public. But if you change the type to private then you get an error.

2. C# Private Access Specifier

If the member function or type member is declared as private then no other type can access the member of that class because that type has restrict his accessibility to their type only. In simple words if the access specifier is private then we can access that only within their class not outside the class. Let see an example to understand c# private access specifier.

using System;

public class Car
{
  private string carName = "Mustang";
}


public class HelloWorld
{
    public static void Main(string[] args)
    {
        Car obj = new Car();
        Console.WriteLine(obj.carName);
    }
}
Output:
'Car.carName' is inaccessible due to its protection level

when you run this code you get an error saying inaccessible due to its level because we have the define carName with private access specifier.

3. C# Protected Access Specifier

In C#, access specifiers protected is also one of the used access specifier which is accessible only from their derived class. Means it is only used if you are using inheritance. If there is no inheritance then all the protected member is act like private members. This can be useful when you want to provide limited access to certain class members for subclasses but not for other classes. Let see an example to understand protected access specifier.

using System;

namespace ProtectedAccessSpecifierDemo
{
    // Base class
    class BaseClass
    {
        // Protected member
        protected string protectedMember = "I am a protected member!";
        
        // Public method to demonstrate access within the base class
        public void ShowProtectedMember()
        {
            Console.WriteLine(protectedMember);
        }
    }

    // Derived class
    class DerivedClass : BaseClass
    {
        // Method to demonstrate access within the derived class
        public void ShowProtectedMemberFromDerived()
        {
            Console.WriteLine(protectedMember);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            BaseClass baseObj = new BaseClass();
            DerivedClass derivedObj = new DerivedClass();

            // Accessing the protected member within the base class
            baseObj.ShowProtectedMember();

            // Accessing the protected member within the derived class
            derivedObj.ShowProtectedMemberFromDerived();

            // The following line would cause a compile-time error because 
            // protected members cannot be accessed directly outside the class or its derived classes
            // Console.WriteLine(baseObj.protectedMember);
        }
    }
}
Output:
I am a protected member!
I am a protected member!

In above program you can see that i have made one class with protected member and this can only be accessible to its derived class. If am trying to access in another class then we get an error saying ‘inaccessible due to its protection level’ but if you want to use the member of that base class then you can use that member in your derived class and then use that derived class anywhere you want to use. So you can easily access the protected member from another class.

4. C# Internal Access Specifier

In C#, access specifiers internal is the default access specifier for all the types if we have not specified the access specifier. If the access specifier is internal then it is accessible from anywhere within their assembly only (means their namespace only). Let see an example to understand internal access specifier in detail.

using System;

namespace InternalAccessSpecifierDemo
{
    // Internal class
    internal class InternalClass
    {
        // Internal member
        internal string internalMember = "I am an internal member!";
        
        // Internal method
        internal void ShowInternalMember()
        {
            Console.WriteLine(internalMember);
        }
    }

    // Public class in the same assembly
    public class PublicClass
    {
        public void AccessInternalClass()
        {
            InternalClass internalObj = new InternalClass();
            internalObj.ShowInternalMember();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            PublicClass publicObj = new PublicClass();
            publicObj.AccessInternalClass();

            // The following code is valid because we are in the same assembly
            InternalClass internalObj = new InternalClass();
            internalObj.ShowInternalMember();

            // If this were another assembly, the following line would cause a compile-time error:
            // internalObj.internalMember = "Attempting to access an internal member from another assembly!";
        }
    }
}
Output:
I am an internal member!
I am an internal member!

In above program you can see that we have used the internal access specifier and also you can see we are in the same assembly. If you access these in another assembly then you get an compile time error.

5. C# Protected Internal Access Specifier

In C#, Access specifiers protected internal access specifier is a combination of protected and internal access specifiers. If you have understood the use of protected and internal accesss specifier then you might had understand what the use case of this access specifier. In protected we can use the members from their derived class and in internal we can use that within their assembly. So protected internal means we can access the member in their assembly and also in another assembly. But from other assemblies, you can access the protected internal member from the derived classes and cannot access from the non-derived classes. Let see an example to understand this in better way.

using System;
namespace FirstAssemblyDemoNamespace
{
    public class FirstAssemblyClass1
    {
        protected internal int Name;
        public void Display1()
        {
            //protected internal Members Accessible with the Containing Type 
            //Where they are created
            Console.WriteLine(Name);
        }
    }
    public class FirstAssemblyClass2 : FirstAssemblyClass1
    {
        public void Display2()
        {
            //We can access protected internal Member from Derived Classes
            //Within the Same Assembly
            Console.WriteLine(Name); //No-Compile Time Error
        }
    }

    public class FirstAssemblyClass3
    {
        public void Dispplay3()
        {
            //We can access protected internal Member from Non-Derived Classes
            //Within the Same Assembly
            AssemblyOneClass1 obj = new AssemblyOneClass1();
            Console.WriteLine(obj.Name); //No-Compile Time Error
        }
    }
}

Lets try to access the protected internal members from a different assembly or a namespace. So to access this member modify your Program.cs class file as follows. From other assemblies, you can access the protected internal member from the derived classes, but you cannot access from the non-derived classes. This is the use of protected internal access specifier.

using AssemblyOne;
using System;
namespace ProtectedInternalAccessSpecifierDemo
{
    public class Program
    {
        static void Main(string[] args)
        {
        }
    }

    public class TestingClass1 : FirstAssemblyClass1
    {
        public void Display4()
        {
            //We can access the protected internal Members from Derived Classes
            //from Other Assemblies
            Console.WriteLine(Name); //No-Compile Time Error
        }
    }

    public class TestingClass2
    {
        public void Dispplay3()
        {
            //We cannot access protected internal Members from Non-Derived Classes
            //from Other Assemblies
            FirstAssemblyClass1 obj = new FirstAssemblyClass1();
            Console.WriteLine(obj.Name); //Compile Time Error
        }
    }
}

6. C# Private Protected Access Specifier

The private protected members are accessible within the class and within the derived class of the same assembly but cannot be accessed from another assembly. Basically it is the combination of private and protected access specifiers. Let see an example to understand this in better way.

using System;
namespace PrivateProtectedAccessSpecifierDemo
{
    public class FirstAssemblyClass1
    {
        private protected int Id;
        public void Display1()
        {
            //Private Protected Members Accessible with the Containing Type 
            //Where they are created
            Console.WriteLine(Id);
        }
    }
    public class FirstAssemblyClass2 : FirstAssemblyClass1
    {
        public void Display2()
        {
            //We can access Private Protected Member from Derived Classes
            //Within the Same Assembly
            Console.WriteLine(Id); //No-Compile Time Error
        }
    }

    public class FirstAssemblyClass3
    {
        public void Dispplay3()
        {
            //We cannot access Private Protected Member from Non-Derived Classes
            //Within the Same Assembly
            AssemblyOneClass1 obj = new AssemblyOneClass1();
            Console.WriteLine(obj.Id); //Compile Time Error
        }
    }
}

If you try to access the private protected member from another assembly you cannot access the private protected members either from the derived classes or from the non-derived classes.

7. C# File Access Specifier

This can only access the type member and member function of the same file. To know more about the C# file access specifier you can go through the microsoft official documentation. Most of the times you will not see this access specifer while developing applications.

Conclusion

In this C# tutorials article, I had discussed about access specifiers with examples. Hope you understand C# access specifiers and like this article. Remember reading articles is not enough to make a good programmer so try to implement at least one program so you will not forget the use-case. In my next article I am going to discuss about encapsulation in csharp programming language.