Encapsulation In C#

Encapsulation in C# - OOPS concept

The wrapping up of data and functions into a single unit (called class) is known as an encapsulation.

Encapsulation is

  • Hiding complexity.
  • Binding the data and the function together.
  • Making complicated methods private.
  • Making an instance variables private.
  • Hiding an unnecessary data and the functions from the end user.

A class can be public or an internal but not a private, protected or protected internal.

Why a class cannot be private or protected

A protected declaration at the namespace level is meaningless. Protected for, or from, what? Access from other namespaces i.e. what 'internal' does.

A namespace has no class hierarchy. Can you inherit from a namespace? No.

Nested class can have all access modifiers. 

  1. class parent {  
  2.     private class Child1 {}  
  3.     protected class Child2 {}  
  4.     protected internal class Child3 {}  
  5. }   

Note

I have created a console Application and a class library (i.e. 2 assemblies) to show the difference between the 5 access modifiers in C# to achieve an encapsulation

private 

  1. namespace ConsoleApplication1 {  
  2.     public class demo {  
  3.         private string name = "some name";  
  4.     }  
  5.     public class Program: demo {  
  6.         static void Main(string[] args) {  
  7.             demo d = new demo();  
  8.             d.name //compile time error, we can’t access the private member  
  9.             ReadLine();  
  10.         }  
  11.     }  
  12. }   

public 

  1. namespace ConsoleApplication1 {  
  2.     public class demo {  
  3.         public string name = "some name";  
  4.     }  
  5.     public class Program: demo {  
  6.         static void Main(string[] args) {  
  7.             demo d = new demo();  
  8.             WriteLine(d.name); // output “some name”  
  9.             ReadLine();  
  10.         }  
  11.     }  
  12. }   

Protected

Protected is only accessible in the same class and in the derived class. This supports cross assembly i.e. if our class is in one assembly and we derive it in another assembly’s class, then we can have access to the protected access modifier members.

Scenario 1 - within same assembly 

  1. namespace ConsoleApplication1 {  
  2.     public class Demo {  
  3.         protected string name = "demo";  
  4.     }  
  5.     public class Program: Demo {  
  6.         static void Main(string[] args) {  
  7.             Demo d = new Demo();  
  8.             WriteLine(d.name); // complie error, we cannot call the protected member by base class reference  
  9.             Program p = new Program();  
  10.             WriteLine(p.name); // we will get the "demo" as output  
  11.             ReadLine();  
  12.         }  
  13.     }  
  14. }   

Scenario 2 - with cross assembly

  1. namespace ClassLibrary1 {  
  2.     public class Demo {  
  3.         protected string name = "demo";  
  4.     }  
  5. }   

It is another assembly, where we are going to inherit it and try to use the variable. 

  1. namespace ConsoleApplication1 {  
  2.     public class Program: Demo {  
  3.         static void Main(string[] args) {  
  4.             Demo d = new Demo();  
  5.             WriteLine(d.name); // complie error, we cannot call the protected member by base class reference  
  6.             Program p = new Program();  
  7.             WriteLine(p.name); // we will get the "demo" as output  
  8.             ReadLine();  
  9.         }  
  10.     }  
  11. }   

Internal

Scenario 1 - within same assembly 

  1. namespace ConsoleApplication1 {  
  2.     public class Demo {  
  3.         internal string name = "demo";  
  4.     }  
  5.     public class Program: Demo {  
  6.         static void Main(string[] args) {  
  7.             Demo d = new Demo();  
  8.             WriteLine(d.name); // we will get the "demo" as output  
  9.             ReadLine();  
  10.         }  
  11.     }  
  12. }   

Scenario 2 - with different assembly 

  1. First assembly  
  2. namespace ClassLibrary1 {  
  3.     public class Demo {  
  4.         internal string name = "demo";  
  5.     }  
  6. }   

Second assembly 

  1. namespace ConsoleApplication1 {  
  2.     public class Program: Demo {  
  3.         static void Main(string[] args) {  
  4.             Demo d = new Demo();  
  5.             WriteLine(d.name); // we will get the compile error  
  6.             ReadLine();  
  7.         }  
  8.     }  
  9. }   

Protected Internal

Scenario 1 - within same assembly 

  1. namespace ConsoleApplication1 {  
  2.     public class Demo {  
  3.         protected internal string name = "demo";  
  4.     }  
  5.     public class Program: Demo {  
  6.         static void Main(string[] args) {  
  7.             Program d = new Program();  
  8.             WriteLine(d.name); // we will get the "demo" as output  
  9.             ReadLine();  
  10.         }  
  11.     }  
  12. }   

Scenario 2 - with different assembly 

  1. First assembly  
  2. namespace ClassLibrary1 {  
  3.     public class Demo {  
  4.         protected internal string name = "demo";  
  5.     }  
  6. }  
  7. Second assembly  
  8. namespace ConsoleApplication1 {  
  9.     public class Program: Demo {  
  10.         static void Main(string[] args) {  
  11.             Program d = new Program();  
  12.             WriteLine(d.name); // we will get the "demo" as output  
  13.             ReadLine();  
  14.         }  
  15.     }  
  16. }