Abstraction in C#

Abstraction defined as the process of identifying only the required characteristics of an object ignoring the irrelevant details.
The properties and behaviors of an object differentiate it from other objects of similar type and also help in classifying/grouping the objects.

Example: 
Consider a real-life scenario of withdrawing money from ATM. 
The user only knows that in ATM machine first enter ATM card, then enter the pin code of ATM card, and then enter the amount which he/she wants to withdraw and at last, he/she gets their money. 
The user does not know about the inner mechanism of the ATM or the implementation of withdrawing money etc. 
The user just simply know how to operate the ATM machine, this is called abstraction.

In C#, abstraction is achieved with the help of Abstract classes.
Abstract Classes
-An abstract class is declared with the help of abstract keyword.
-In C#, you are not allowed to create objects of the abstract class. Or in other words, you cannot use the abstract class directly with the new operator.
-Class that contains the abstract keyword with all of its methods is known as pure Abstract Base Class.
-You are not allowed to declare the abstract methods outside the abstract class.
-You are not allowed to declare abstract class as Sealed Class.

There are situations in which we want to define a superclass that declares the structure of a given abstraction without providing a complete implementation of every method. 
That is, sometimes we want to create a superclass that only defines a generalized form that will be shared by all of its subclasses, leaving it to each subclass to fill in the details.
Consider a classic “shape” example, perhaps used in a computer-aided design system or game simulation. 
The base type is “shape” and each shape has a color, size and so on. 
From this, specific types of shapes are derived(inherited)-circle, square, triangle and so on – each of which may have additional characteristics and behaviors. 

The following are some of the key points −
You cannot create an instance of an abstract class.
You cannot declare an abstract method outside an abstract class.
When a class is declared sealed, it cannot be inherited, abstract classes cannot be declared sealed.


Example

using System;
namespace Demo {
   abstract class Shape {
      public abstract int area();
   }
   
   class Rectangle:  Shape {
      private int length;
      private int width;
      
      public Rectangle( int a = 0, int b = 0) {
         length = a;
         width = b;
      }
      public override int area () { 
         Console.WriteLine("Rectangle class area :");
         return (width * length); 
      }
   }
   class RectangleTester {
      static void Main(string[] args) {
         Rectangle r = new Rectangle(20, 15);
         double a = r.area();
         Console.WriteLine("Area: {0}",a);
         Console.ReadKey();
      }
   }
}

Output-
Rectangle class area :
Area: 300

List vs Dictionary in C#

Both lists and dictionaries belong to Generics collections that is they used to store collections of data. 
Both Dictionary <TKey, TValue> and List <T> are similar both have the random access data structures on top of the .NET framework. 
The Dictionary is based on a hash table that means it uses a hash lookup, which is an efficient algorithm to look up things, on the other hand, a list, have to go and check element by element until it finds the result from the beginning. 

The Dictionary uses the hashing algorithm to search for the element (data). 
A Dictionary first calculates a hash value for the key and this hash value leads to the target data bucket. 
After that, each element in the bucket needs to be checked for equality. 
But actually, the list will be faster than the dictionary on the first item search because nothing to search in the first step. 
But in the second step, the list has to look through the first item and then the second item. So each step the lookup takes more and more time. 
The larger the list, the longer it takes. 
Of course, the Dictionary in principle has a faster lookup with O(1) while the lookup performance of a List is an O(n) operation.

The Dictionary maps a key to a value and cannot have duplicate keys, whereas a list just contains a collection of values. 
Also, Lists allow duplicate items and support linear traversal.


Consider the following example:

Dictionary<string, int> dictionary = new Dictionary<string, int>();
List<int> newList = new List<int>();
Add data to the list
newList.Add(data);
A list can simply add the item at the end of the existing list item. 

Add data to the Dictionary
dictionary.Add(key, data);
When you add data to a Dictionary, you should specify a unique key to the data so that it can be uniquely identified.


A Dictionary has a unique identifier, so whenever you look up a value in a Dictionary, the runtime must compute a hash code from the key. 
This optimized algorithm implemented by some low-level bit shifting or modulo divisions. 
We determine the point at which Dictionary becomes more efficient for lookups than List.

The Find() method of the List class loops through each object in the list until a match is found. 
So, if we want to lookup a value using a key, then dictionary is better for performance over list. 
So, we need to use dictionary when we know the collection will be primarily used for lookups.