Access Modifier In C# With Example

Introduction

Access modifiers are keywords used to specify the declared accessibility of a member or a type. These define the permission level to type members ( Methods, Properties, Events, Variables).

Background

All type and type members have an accessibility level which controls whether they can be used by the code in the same assembly in which the type declared or the code in the other assembly.

Points of Interest

  • Access modifiers are not allowed on namespaces. Namespaces have no access restrictions
  • Top-Level types, which are not nested into other types, can only have internal or public accessibility. The default accessibility for these types is internal.
  • The accessibility of a nested type depends on its accessibility domain, which is determined by both the declared accessibility of the member and the accessibility domain of the immediately containing type.
  • Private,Protected and Protected Internal class we can't declare explicityly within namespace.
  • Struct members cannot be protected because the struct cannot be inherited.
  • The drived class can't have higher accessibility than its base class, i.e. you can't have a public class that drived from a internal class.
  • The accessibility of a member can never be higher than the accessibility of its containing type.
  • Interface can only be public or internal. And default to internal.
  • Enum are default to public so not accept any modifer.
  • Delegates are default to internal.

Description

Given below are the major access modifiers used with type or type members.

  • Public
  • Protected
  • Internal
  • Protected Internal
  • Private

Public

Using Public, access is not restricted; it means type or type members are accessible by the code in the same or other assembly that referenced it.

  1. public class SampleClass1  
  2.     {  
  3.         // Public variable  
  4.         public static int myPublicInt;  
  5.     }  
  6.   
  7. class Program  
  8.     {  
  9.         static void Main(string[] args)  
  10.         {  
  11.              //Access to SampleClass1 fields  
  12.             SampleClass1.myPublicInt = 1;      // Access is unlimited  
  13.   
  14.   
  15.             Console.WriteLine("Press any key to exit!");  
  16.             Console.ReadLine();  
  17.         }  
  18.     }  

Protected

Using Protected, access is limited to the class which declares that member and the immediate class which inherits that class. A protected member of a base class is accessible in a drived classs only if the access takes place through the derived class type.

Example

  1. class ProtectedSample  
  2.     {  
  3.         protected string Name = string.Empty;  
  4.   
  5.         protected void Display()  
  6.         {  
  7.             Console.WriteLine("Name: " + Name);  
  8.         }  
  9.     }  
  10.   
  11.     class Drived : ProtectedSample  
  12.     {  
  13.         Drived()  
  14.         {  
  15.             this.Name = "John";  // Accessible  
  16.         }  
  17.   
  18.         // Method will call protectedSample class display method  
  19.         public void DisplayName()  
  20.         {  
  21.             this.Display();  
  22.         }  
  23.     }  
  24.   
  25.     class Other  
  26.     {  
  27.         Other()  
  28.         {  
  29.             (new ProtectedSample()).Name = "Mike"// Error: Inaccessible due to its protection level  
  30.         }  
  31.     }  

Example 2

  1. class ProtectedSample2  
  2.     {  
  3.         protected string Name = string.Empty;  
  4.   
  5.         static void Initialize(ProtectedSample2 objA, Drive objDrive)  
  6.         {  
  7.             objA.Name = "Mike";  
  8.             objDrive.Name = "Clark";  
  9.         }  
  10.     }  
  11.   
  12.     class Drive : ProtectedSample2  
  13.     {  
  14.         static void Initialize(ProtectedSample2 objA, Drive objDrive)  
  15.         {  
  16.             objA.Name = "Mike";     // Error: Cannot access protected member via a qualifier of type   
  17.                                     // 'ProtectedSample2', the qualifier must be of type 'Drive'  
  18.             objDrive.Name = "John";  
  19.         }  
  20.     }  

Internal

Using Internal, access is limited to the current assembly not by other assembly. A common use of internal access is in component-based development because it enables a group of components to cooperate in a private manner without being exposed to the rest of the application code.

  1. namespace Cons.Accessibility  
  2. {  
  3.    internal class InternalSample  
  4.     {  
  5.         public void Display()  
  6.         {  
  7.             Console.WriteLine("In InternalSample.Display");  
  8.         }  
  9.     }  
  10. }  
  11. namespace Cons.Other  
  12. {  
  13.     class Test  
  14.     {  
  15.         Cons.Accessibility.InternalSample obj = new Accessibility.InternalSample();  
  16.           
  17.         public void Display()  
  18.         {  
  19.             obj.Display();  // Valid  
  20.         }  
  21.     }  
  22. }  
  23.   
  24. // In different Assembly  
  25. using Cons.Accessibility;  
  26. namespace TestingApplication  
  27. {  
  28.     class Program  
  29.     {  
  30.         static void Main(string[] args)  
  31.         {  
  32.             InternalSample obj = new Cons.Accessibility.InternalSample();  // Error: Inaccessible due   
  33.                                                                            // to protection level  
  34.         }  
  35.     }  
  36. }  

Protected Internal

Using Protected Internal, accessibility is limited to the code in assembly in which it is declared, or from within a drive class in another assembly. Access from another assembly must take place within a class declaration that derives from the class in which the protected internal element is declared, and it must take place through an instance of the derived class type.

  1. namespace Cons.Accessibility  
  2. {  
  3.     public class ProtectedInternalSample  
  4.     {  
  5.         protected internal string Name = string.Empty;  
  6.   
  7.         protected void Display()  
  8.         {  
  9.             Console.WriteLine("Name: " + this.Name);    // Valid  
  10.         }  
  11.     }  
  12.   
  13.     public class PIDrived: ProtectedInternalSample  
  14.     {  
  15.         PIDrived()  
  16.         {  
  17.             this.Name = "John";     // Valid  
  18.         }  
  19.     }  
  20. }  
  21.   
  22. // Other Namespace but same assembly  
  23. namespace Others  
  24. {  
  25.     class Other  
  26.     {  
  27.         Other()  
  28.         {  
  29.             Cons.Accessibility.ProtectedInternalSample obj = new   
  30.                        Cons.Accessibility.ProtectedInternalSample();  
  31.             obj.Name = "Mike";  
  32.         }  
  33.     }  
  34. }  
  35.   
  36. // Diff assembly  
  37. using Cons.Accessibility;  
  38. namespace TestingApplication  
  39. {  
  40.     class Program : ProtectedInternalSample  
  41.     {  
  42.         public void UpdateName()  
  43.         {  
  44.             Name = "Clark"// Valid  
  45.         }  
  46.     }  
  47. }  

In the above example, if we remove Protected keyword from the Name variable, then it will not be accessible in diff assembly.

Private

Using Private, accessibility is limited to the code that are only in containted type.

  1. class PrivateSample  
  2.     {  
  3.         private string Name = string.Empty;  
  4.   
  5.         public void Initialize()  
  6.         {  
  7.             this.Name = "John";  
  8.         }  
  9.     }  
  10.   
  11.     class POther  
  12.     {  
  13.         public void Initialize()  
  14.         {  
  15.             PrivateSample obj = new PrivateSample();  
  16.             obj.Name = "Mike";    // Error: Inaccessible due to protection level  
  17.             obj.Initialize();     // Valid  
  18.         }  
  19.     }  

Hope this will add some knowledge to your knowledge base.