OOP Series #2: Understanding Access Specifiers In C#

OOP Series #1: Building and Consuming a Class Library (DLL) Using C#


Access modifiers and specifiers are keywords (private, public, internal, protected and protected internal) to specify the accessibility of a type and its members.

C# has 5 access specifier or access modifier keywords; those are private, public, internal, protected and protected Internal.

Usage of Access Specifiers

limits the accessibility of a member to within the defined type, for example if a variable or a functions is being created in a ClassA and declared as private then another ClassB can't access that.

public: has no limits, any members or types defined as public can be accessed within the class, assembly even outside the assembly. Most DLLs are known to be produced by public class and members written in a .cs file.

internal: internal plays an important role when you want your class members to be accessible within the assembly. An assembly is the produced .dll or .exe from your .NET Language code (C#). Hence, if you have a C# project that has ClassA, ClassB and ClassC then any internal type and members will become accessible across the classes with in the assembly.

protected: plays a role only when inheritance is used. In other words any protected type or member becomes accessible when a child is inherited by the parent. In other cases (when no inheritance) protected members and types are not visible.

Protected internal: is a combination of protected and internal both. A protected internal will be accessible within the assembly due to its internal flavor and also via inheritance due to its protected flavor.

Code Sample 

  1. public class AccessModifier  
  2. {    
  3.       //Available only to the container Class 
  4.       private string privateVariable;

  5.       // Available in entire assembly across the classes 
  6.       internal string internalVariable;  

  7.       //Available in the container class and the derived class   
    protected string protectedVariable; 

    //Available to the container class, entire assembly and to outside    
          public string publicVariable;   

  8.       //Available to the derived class and entire assembly as well
    protected internal string protectedInternalVariable;  

  9.       private string PrivateFunction()  
  10.       { 
  11.           return privateVariable;  
  12.       }  

  13.       internal string InternalFunction()
  14.       {    
  15.           return internalVariable; 
  16.       }    

  17.       protected string ProtectedFunction() 
  18.       {       
  19.           return protectedVariable; 
  20.       }  

  21.       public string PublicFunction() 
  22.       {       
  23.           return publicVariable; 
  24.       }  

  25.       protected internal string ProtectedInternalFunction()  
  26.       {      
  27.            return protectedInternalVariable;  
  28.       }
  29. }   
Now to show the behavior of how these class members are exposed to another class depending upon their scope defined via modifier/specifier and when we create an object or inherit from the preceding created class named "AccessModifier".

Now to use this class and class members we need to either create an object or inherit from this class.

Object Creation

Let's see what happens if we decide to create an object of the class "AccessModifier" shown in the code above. As per the rule private and protected must not be visible via an object?

objection creation

Showing members available when an object is created of the given class.

As you can see in the intellisense popup that private and protected are not visible. private is not shown due to its limited scope within the class but the key thing here is that protected is not being displayed by an object since protected members are only available via inheritance.

However, protected internal is visible because it's a mix of two keywords and in the case of class instantiation, in other words object creation internal is showing its effect.

Members shown: internal, public, protected internal.

Members NOT shown: private, protected.

Inherit from Class

So if we derive another class "CallAccessModifier" from the parent class " AccessModifier " then "private" type members will not be visible because its considered as outside the scope of parent class.

But "protected" members are the ones that become available only during the inheritance (when a child is derived from a parent class) as shown via image below.

Inherit from class

Showing class members availability through inheritance.

Note: The "this" keyword refers to the current instance of the class and accesses its members. In the image above this keyword shows all the available members with the class.

If you notice in the preceding shown image it clearly shows all the protected members are visible due to virtue of inheritance, along with other members with scope defined as internal, public and protected internal.

However, protected internal is visible because it's a mix of two keywords and in the case of inheritance protected is showing its effect.

Members shown: internal, public, protected and protected internal

Members NOT shown: private

YouTube Video