C# Access Modifiers , C# Access Specifiers

Access Modifiers ( Access Specifiers ) describes as the scope of accessibility of an Object and its members. All C# types and type members have an accessibility level . We can control the scope of the member object of a class using access specifiers. We are using access modifiers for providing security of our applications. When we specify the accessibility of a type or member we have to declare it by using any of the access modifiers provided by C# language.

C# provide six access modifiers , they are as follows :

  1. private
  2. public
  3. protected
  4. internal
  5. protected internal
  6. Private Protected (C# version 7.2 and later)

Private Access Modifier

The scope of the accessibility is limited only inside the classes or struct in which they are declared. The private members cannot be accessed outside the class and it is the least permissive access level .

example
using System; namespace ConsoleApplication1 { class PrivateAccess { private string msg = "This variable is private "; private void disp(string msg) { Console.WriteLine("This function is private : " + msg); } } class Program { static void Main(string[] args) { PrivateAccess privateTest = new PrivateAccess(); Console.WriteLine(privateTest.msg);// Cannot Access private variable here privateTest.disp("Hello !!"); // Cannot Access private function here } } }
output
Error 1 'ConsoleApplication1.PrivateAccess.msg' is inaccessible due to its protection level Error 2 'ConsoleApplication1.PrivateAccess.disp(string)' is inaccessible due to its protection level

Here we can see the private variable and function in the PrivateAccess class cannot access in the main() function because main() function is in a separated class "Program" . The scope of the accessibility of private access members limited only inside the classes or struct in which they are declared. So, the private members cannot be accessed outside the class and it is the least permissive access level.

example
using System; namespace ConsoleApplication1 { class Program { private string msg = "This variable is private "; private void disp(string msg) { Console.WriteLine("This function is private : " + msg); } static void Main(string[] args) { Program pr = new Program(); Console.WriteLine(pr.msg);// / Accessing private variable inside the class pr.disp("Hello !!"); // Accessing private function inside the class } } }
output
This variable is private This function is private : Hello !!

Here we made a change to the above program that we move the private variable and function in the same class. So, we can access the private variable and private function from main() because private access modifiers scope is limited only inside the classes or struct in which they are declared.

Public Access Modifier


C# Public Access Modifier

public is the most common access specifier in C# . It can be access from anywhere, that means there is no restriction on accessibility. The scope of the accessibility is inside class as well as outside. The type or member can be accessed by any other code in the same assembly or another assembly that references it.

example
using System; namespace ConsoleApplication1 { class PublicAccess { public string msg = "This variable is public"; public void disp(string msg) { Console.WriteLine("This function is public : " + msg); } } class Program { static void Main(string[] args) { PublicAccess pAccess = new PublicAccess(); Console.WriteLine(pAccess.msg); // Accessing public variable pAccess.disp("Hello !!"); // Accessing public function } } }
output
This variable is public This function is public : Hello !!

Here we can access the variable and function in the main() , because the variable and function declared as public.

Protected Access Modifier

The scope of accessibility is limited within the class or struct and the class derived (Inherited )from this class.

example
using System; namespace ConsoleApplication1 { class ProtectedAccess { protected string msg = "This variable is protected "; protected void disp(string msg) { Console.WriteLine("This function is protected : " + msg); } } class Program { static void Main(string[] args) { ProtectedAccess prAccess = new ProtectedAccess(); Console.WriteLine(prAccess.msg); // Cannot access protected variable here prAccess.disp("Hello !!"); // Cannot access protected function here } } }
output
Error 1 'ConsoleApplication1.ProtectedAccess.msg' is inaccessible due to its protection level Error 2 'ConsoleApplication1.ProtectedAccess.disp(string)' is inaccessible due to its protection level


C# Protected Access Modifier

Here we can see the protected variable and function in the ProtectedAccess class cannot access in the main() function because main() function is in a separated class "Program" . The following program will make you clear that how a protected variable and function can access from inherited calss.

example
using System; namespace ConsoleApplication1 { class ProtectedAccess { protected string msg = "This variable is protected "; protected void disp(string msg) { Console.WriteLine("This function is protected : " + msg); } } class Program : ProtectedAccess { static void Main(string[] args) { Program pr = new Program(); Console.WriteLine(pr.msg); // Accessing protected variable pr.disp("Hello !!"); // Accessing protected function } } }

Here we made a change to the above program that the class program is in from class "ProtectedAccess" .

class Program : ProtectedAccess

So, we can access the protected variable and protected function from main() because Protected access modifiers scope of accessibility is limited within the class or struct and the class derived (Inherited )from this class.

Internal Access Modifier

The internal access modifiers can access within the program that contain its declarations and also access only within files in the same assembly level but not from another assembly.

example
using System; namespace ConsoleApplication1 { class InternalAccess { internal string msg = "This variable is internal"; internal void disp(string msg) { Console.WriteLine("This function is internal : " + msg); } } class Program { static void Main(string[] args) { InternalAccess iAccess = new InternalAccess(); Console.WriteLine(iAccess.msg); // Accessing internal variable iAccess.disp("Hello !!"); // Accessing internal function Console.ReadKey(); } } }
output
This variable is internal This function is internal : Hello !!

Protected Internal Access Modifier

Protected internal is the same access levels of both protected and internal . It can access anywhere in the same assembly also be accessed within a derived class in another assembly.

example
using System; namespace ConsoleApplication1 { class InternalAccess { protected internal string msg = "This variable is protected internal"; protected internal void disp(string msg) { Console.WriteLine("This function is protected internal : " + msg); } } class Program { static void Main(string[] args) { InternalAccess iAccess = new InternalAccess(); Console.WriteLine(iAccess.msg); // Accessing internal variable iAccess.disp("Hello !!"); // Accessing internal function Console.ReadKey(); } } }
output
This variable is protected internal This function is protected internal : Hello !!

Private Protected Access Modifier

The private protected access modifier is valid in C# version 7.2 and later .

The protected internal modifier really means protected OR internal, that is - member X is accessible to child classes and also to any class in the current assembly , even if that class is not child of class X (so restriction implied by "protected" is relaxed).

C# version 7.2 and later , the new modifier private protected really means protected AND also internal. That is - member is accessible only to child classes which are in the same assembly, but not to child classes which are outside assembly (so restriction implied by "protected" is narrowed - becomes even more restrictive). That is useful if you build hierarchy of classes in your assembly and do not want any child classes from other assemblies to access certain parts of that hierarchy.

The following example contains two files, Assembly1.cs and Assembly2.cs . The first file contains a public base class, MyBaseClass, and a type derived from it, MyDerivedClass1. MyBaseClass owns a private protected member, count, which MyDerivedClass1 tries to access in two ways. The first attempt to access count through an instance of MyBaseClass will produce an error. However, the attempt to use it as an inherited member in MyDerivedClass1 will succeed. In the second file, an attempt to access count as an inherited member of MyDerivedClass2 will produce an error, as it is only accessible by derived types in Assembly1.

example
// Assembly1.cs // Compile with: /target:library public class MyBaseClass { private protected int count = 0; } public class MyDerivedClass1 : MyBaseClass { void callMe() { MyBaseClass obj = new MyBaseClass(); obj.count = 5; // Error CS1540, because the variable count can only be accessed by // classes derived from MyBaseClass. count = 5; // OK, accessed through the current derived class instance } }
example
// Assembly2.cs // Compile with: /reference:Assembly1.dll class MyDerivedClass2 : MyBaseClass { void callMe() { count = 10; // Error CS0122, because count can only be // accessed by types in Assembly1 } }

Protected Internal Vs. Private Protected

protected internal

  1. protected in another assembly: accessible only in the child classes.
  2. internal in the current assembly: accessible by everyone in the current assembly.

private protected

  1. private in another assembly: is not accessible.
  2. protected in the current assembly: accessible only in the child classes.

Default access modifiers in C#


C# Default access modifier

When no access modifier is set, a default access modifier is used. So there is always some form of access modifier even if it's not set. The default access for everything in C# is "the most restricted access you could declare for that member".

  1. Namespaces implicitly have public declared accessibility. No access modifiers are allowed on C# namespace declarations.

  2. C# Types declared in compilation units or namespaces can have public or internal declared accessibility and default to internal declared accessibility.

  3. Class members can have any of the five kinds of declared accessibility and default to private declared accessibility. (It is important to note that a type declared as a member of a class can have any of the five kinds of declared accessibility, whereas a type declared as a member of a namespace can have only public or internal declared accessibility.)

  4. Struct members can have public, internal, or private declared accessibility and default to private declared accessibility because C# structs are implicitly sealed. Struct members introduced in a struct (that is, not inherited by that struct) cannot have protected or protected internal declared accessibility. (Note that a type declared as a member of a struct can have public, internal, or private declared accessibility, whereas a type declared as a member of a namespace can have only public or internal declared accessibility.)

  5. Interface members implicitly have public declared accessibility. No access modifiers are allowed on C# interface member declarations.

  6. C# Enumeration members implicitly have public declared accessibility. No access modifiers are allowed on enumeration member declarations.

Static modifier

The static modifier on a class means that the class cannot be instantiated, and that all of its members are static. A static member has one version regardless of how many instances of its enclosing type are created.