Access Modifiers in C#
Access Modifiers are keywords that define the accessibility of a member, class or datatype in a program. These are mainly used to restrict unwanted data manipulation by external programs or classes. There are 4 access modifiers (public, protected, internal, private) which defines the 6 accessibility levels as follows:
The Accessibility table of these modifiers is given below:
public | protected | internal | protected internal | private | private protected | |
---|---|---|---|---|---|---|
Entire program | Yes | No | No | No | No | No |
Containing class | Yes | Yes | Yes | Yes | Yes | Yes |
Current assembly | Yes | No | Yes | Yes | No | No |
Derived types | Yes | Yes | No | Yes | No | No |
Derived types within current assembly | Yes | Yes | Yes | Yes | No | Yes |
public Accessibility Level
Access is granted to the entire program. This means that another method or another assembly which contains the class reference can access these members or types. This access modifier has the most permissive access level in comparison to all other access modifiers.
Syntax:
public TypeName
Example: Here, we declare a class Student which consists of two class members rollNo and name which are public. These members can access from anywhere throughout the code in the current and another assembly in the program. The methods getRollNo and getName are also declared as public.
csharp
// C# Program to show the use of // public Access Modifier using System; namespace publicAccessModifier { class Student { // Declaring members rollNo // and name as public public int rollNo; public string name; // Constructor public Student( int r, string n) { rollNo = r; name = n; } // methods getRollNo and getName // also declared as public public int getRollNo() { return rollNo; } public string getName() { return name; } } class Program { // Main Method static void Main( string [] args) { // Creating object of the class Student Student S = new Student(1, "Astrid" ); // Displaying details directly // using the class members // accessible through another method Console.WriteLine( "Roll number: {0}" , S.rollNo); Console.WriteLine( "Name: {0}" , S.name); Console.WriteLine(); // Displaying details using // member method also public Console.WriteLine( "Roll number: {0}" , S.getRollNo()); Console.WriteLine( "Name: {0}" , S.getName()); } } } |
Roll number: 1 Name: Astrid Roll number: 1 Name: Astrid
protected Accessibility Level
Access is limited to the class that contains the member and derived types of this class. It means a class which is the subclass of the containing class anywhere in the program can access the protected members.
Syntax:
protected TypeName
Example: In the code given below, the class Y inherits from X, therefore, any protected members of X can be accessed from Y but the values cannot be modified.
csharp
// C# Program to show the use of // protected Access Modifier using System; namespace protectedAccessModifier { class X { // Member x declared // as protected protected int x; public X() { x = 10; } } // class Y inherits the // class X class Y : X { // Members of Y can access 'x' public int getX() { return x; } } class Program { static void Main( string [] args) { X obj1 = new X(); Y obj2 = new Y(); // Displaying the value of x Console.WriteLine( "Value of x is : {0}" , obj2.getX()); } } } |
Value of x is : 10
internal Accessibility Level
Access is limited to only the current Assembly, that is any class or type declared as internal is accessible anywhere inside the same namespace. It is the default access modifier in C#.
Syntax:
internal TypeName
Example: In the code given below, The class Complex is a part of internalAccessModifier namespace and is accessible throughout it.
csharp
// C# Program to show use of // internal access modifier // Inside the file Program.cs using System; namespace internalAccessModifier { // Declare class Complex as internal internal class Complex { int real; int img; public void setData( int r, int i) { real = r; img = i; } public void displayData() { Console.WriteLine( "Real = {0}" , real); Console.WriteLine( "Imaginary = {0}" , img); } } // Driver Class class Program { // Main Method static void Main( string [] args) { // Instantiate the class Complex // in separate class but within // the same assembly Complex c = new Complex(); // Accessible in class Program c.setData(2, 1); c.displayData(); } } } |
Real = 2 Imaginary = 1
Note: In the same code if you add another file, the class Complex will not be accessible in that namespace and compiler gives an error.
csharp
// C# program inside file xyz.cs // separate nampespace named xyz using System; namespace xyz { class text { // Will give an error during compilation Complex c1 = new Complex(); c1.setData(2, 3); } } |
error CS1519
protected internal Accessibility Level
Access is limited to the current assembly or the derived types of the containing class. It means access is granted to any class which is derived from the containing class within or outside the current Assembly.
Syntax:
protected internal TypeName
Example: In the code given below, the member ‘value‘ is declared as protected internal therefore it is accessible throughout the class Parent and also in any other class in the same assembly like ABC. It is also accessible inside another class derived from Parent, namely Child which is inside another assembly.
csharp
// Inside file parent.cs using System; public class Parent { // Declaring member as protected internal protected internal int value; } class ABC { // Trying to access // value in another class public void testAccess() { // Member value is Accessible Parent obj1 = new Parent(); obj1.value = 12; } } |
csharp
// Inside file GFg.cs using System; namespace GFG { class Child : Parent { // Main Method public static void Main(String[] args) { // Accessing value in another assembly Child obj3 = new Child(); // Member value is Accessible obj3.value = 9; Console.WriteLine( "Value = " + obj3.value); } } } |
Value = 9
private Accessibility Level
Access is only granted to the containing class. Any other class inside the current or another assembly is not granted access to these members.
Syntax:
private TypeName
Example: In this code we declare the member value of class Parent as private therefore its access is restricted to only the containing class. We try to access value inside of a derived class named Child but the compiler throws an error {error CS0122: ‘PrivateAccessModifier.Parent.value’ is inaccessible due to its protection level}. Similarly, inside main {which is a method in another class}. obj.value will throw the above error. So we can use public member methods that can set or get values of private members.
csharp
// C# Program to show use of // the private access modifier using System; namespace PrivateAccessModifier { class Parent { // Member is declared as private private int value; // value is Accessible // only inside the class public void setValue( int v) { value = v; } public int getValue() { return value; } } class Child : Parent { public void showValue() { // Trying to access value // Inside a derived class // Console.WriteLine( "Value = " + value ); // Gives an error } } // Driver Class class Program { static void Main( string [] args) { Parent obj = new Parent(); // obj.value = 5; // Also gives an error // Use public functions to assign // and use value of the member 'value' obj.setValue(4); Console.WriteLine( "Value = " + obj.getValue()); } } } |
Value = 4
private protected Accessibility Level
Access is granted to the containing class and its derived types present in the current assembly. This modifier is valid in C# version 7.2 and later.
Syntax:
private protected TypeName
Example: This code is same as the code above but since the Access modifier for member value is ‘private protected’ it is now accessible inside the derived class or Parent namely Child. Any derived class that maybe present in another assembly will not be able to access these private protected members.
csharp
// C# Program to show use of // the private protected // Accessibility Level using System; namespace PrivateProtectedAccessModifier { class Parent { // Member is declared as private protected private protected int value; // value is Accessible only inside the class public void setValue( int v) { value = v; } public int getValue() { return value; } } class Child : Parent { public void showValue() { // Trying to access value // Inside a derived class Console.WriteLine( "Value = " + value); // value is accessible } } // Driver Code class Program { // Main Method static void Main( string [] args) { Parent obj = new Parent(); // obj.value = 5; // Also gives an error // Use public functions to assign // and use value of the member 'value' obj.setValue(4); Console.WriteLine( "Value = " + obj.getValue()); } } } |
Value = 4
Important Points:
- Namespaces doesn’t allow the access modifiers as they have no access restrictions.
- The user is allowed to use only one accessibility at a time except the private protected and protected internal.
- The default accessibility for the top-level types(that are not nested in other types, can only have public or internal accessibility) is internal.
- If no access modifier is specified for a member declaration, then the default accessibility is used based on the context.