Sunday, September 20, 2020

Basic Concepts of JavaScript

Syntax Parsers

A program that reads your code and determines what it does and if it's grammar is valid. 

The code we written can not understand by the computer. So the code needed to be read character by character and convert it to the set of instructions that the computer can understand. To do that ,there is a compiler/ interpreter and Syntax Parser is part of it. 


Lexical Environment

Lexical environment is where something sits physically in the code we write. 

Lexical environment stores the variable defined in the function during the execution of that function.

Execution Context

Execution context is a wrapper to help manage the code that is running. There are lot of lexical environments and which one is currently running is managed via execution contexts. 

When ever we run the JavaScript code, it runs inside the execution context.

Name Value Pair

Name value pair is a name which maps to unique value. 

The name may be defined more than once, but only can have one value in a given context.

In below example, Name is "Address" and Value is "Main 100".

Address =  'Main 100'

Objects

Object is a collection of Name Value pairs. 

In below example, Address and Apartment are objects. 


Global Execution Context

Base execution context is the global execution context. When we say Global, it means the things where accessible in everywhere in our code. Global Execution creates two things which are Global Object and  special variable 'this'. 

eg : Inside the browser, the global object is 'window'. 

If there is any variables or functions which are not in the inside of the functions are attached to the global object (window). 
// Below code is not in the inside of the function. So that is global. 	
var a = 'Hello World';

function b(){  
}


Hoisting

Hoisting is setting up memory space for variables and functions. 

Before our code executing line by line, Java Script engine sets up the memory space for variables and functions created in entire code. So those functions and variables exists in the memory. When the code begins to execute line by line, it can access them. However when it comes to variables little bit different. When Java Script engine sets up the memory for a variable, it does not any assigned value for that.  That's why, it returns "undefined'.

See below Example. Even though, 'b' function call  is in top of the code, it will still executing not like other programming languages. And instead of error , 'a' is undefined. 






Undefined

When Java Scripts sets up the memory space for the variables or method,  automatically "undefined"  value will be set to them as the initial value . 

Single Threaded and Synchronous

Single threaded means one command one at a time. 

Synchronous means one line of code is executed at a time in the order it appears. 

Function Invocation

Function invocation means running a function. In Java Script we can use parenthesis '( )'.

Every time function is called a new execution context will be created. 


Variable Environment

Variable environment is the place where the variables lives and how they are related to each other.

When we have declare variable with the same name in different methods, it will be executed their own scope and in their own execution context. Even though they have same name , they are unique, distinct and they don't touch each other.  See the below example. 


Scope Chain

When a variable is used in JavaScript, the JavaScript engine will try to find the variable’s value in the current execution context. If it could not find the variable, it will look into the outer reference somewhere down below in the execution stack until it finds the variable or reaches global scope.  Outer Reference depends on where the function sits lexically. 



In below code, b() function physically sits inside a(). 


Scope

Scope in JavaScript refers to the accessibility or visibility of variables. That is, which parts of a program have access to the variable or where the variable is visible.

  •  Global Scope
Any variable that’s not inside any function or block (a pair of curly braces), is inside the global scope. The variables in global scope can be accessed from anywhere in the program.

  •   Local Scope or Function Scope 
Variables declared inside a function is inside the local scope. They can only be accessed from within that function, that means they can’t be accessed from the outside code. For example:
function a() {
  var greeting = 'Hello World!';
  console.log(greeting);
}

// Prints 'Hello World!'
a();

// Uncaught ReferenceError: greeting is not defined
console.log(greeting);

  • Block Scope
ES6(ECMAScript 6) introduced let variable, unlike var variables, they can be scoped to the nearest pair of curly braces. That means, they can’t be accessed from outside that pair of curly braces. For example:
function a() {
  var age = 100;
  if (age > 12){
    let dogYears = age * 7; //using let
    var noOfYears = age * 7; //using var
    console.log(`You are ${dogYears} dog years old!`);
  }
 
// Prints '700'
console.log(noOfYears);
    
// Uncaught Reference Error: dogYears is not defined
console.log(dogYears);
}

a();

References: Udemy.com

Saturday, September 19, 2020

LINQ

  • LINQ stands for Language Integrated Query. LINQ gives to capability to query objects.
  • We can query, 
    • Objects in memory eg :Collections)(LINQ to Objects), 
    • Databases (LINQ to SQL), 
    • XML(LINQ to XML) 
    • ADO.NET Data Sets (LINQ to Data Sets). 
    •  class Book
          {
              public string Name { get; set; }
              public decimal Price { get; set; }
          }
      
      class BookRepository
          {
      
              public IEnumerable GetBooks()
              {
                  var boooks = new List()
                  {
                      new Book() { Name="Fundamentals of C#" , Price = 20 },
                      new Book() { Name="ASP.NET MVC" , Price = 30},
                      new Book() { Name="Entity Framework" , Price = 12 },
                      new Book() { Name ="Java" , Price = 10 },
                      new Book() { Name = "Web API" , Price = 15 },
                      new Book() { Name="Java Script Basics" , Price= 25 }
                  };
      
                  return boooks;
              }
          }
      
      class Program
          {
              static void Main(string[] args)
              {
                  var books = new BookRepository().GetBooks();
                  var cheapbooks = new List();
                  
                  if(books != null)
                  {
                      cheapbooks = books.Where(book=>book.Price >12).ToList();
                  }
      
                  foreach (var book in cheapbooks)
                  {
                      Console.WriteLine(book.Name);
                  }
      
                  Console.Read();
              }
          }
      
      
Some of the more frequently used standard query methods and keywords

Method/Keywords Syntax Description
Where
Where(Predicate) Filters a sequence of values based on a predicate.
OrderBy OrderBy(Predicate) Sorts the elements of a sequence in ascending order.
ThenBy ThenBy(Predicate) Performs a subsequent ordering of the elements in a sequence in ascending order.
Select Select(Predicate) Projects each element of a sequence into a new form.
Take Take(int) Returns a specified number of contiguous elements from the start of a collection/sequence.
Skip Skip(int) Bypasses a specified number of elements in a sequence and then returns the remaining elements.
FirstOrDefault FirstOrDefault(Predicate) Returns the first element of a sequence, or a default value if no element is found.
First First(Predicate) Returns the first element of a sequence.
Single Single(Predicate) Returns the only element of a sequence that satisfies a specified condition, and throws an exception if more than one such element exists.

Thursday, September 17, 2020

Extension Methods

  • Extension methods allow us to add new methods to an existing class without changing its source code or creating a new class that inherits from it. 
As an example , suppose we need a shorten version of a very long post. In that case, there is no instance method in String class to get it done. Also we can not inherit the String class as it is sealed class and can not change or modify. In that situation, we can use extension methods to add new methods to an existing class.  
  • Extension methods are defined as static methods but are called by using instance method syntax. Their first parameter specifies which type the method operates on. The parameter is preceded by the this modifier.
  • namespace ExtentionMethods
    {
        public static class StringExtention
        {
            //numofwords is 5 means we need first 5 words of the str
            public static string Shorten(this string str, int numofwords)
            {
                if (numofwords == 0)
                    return " ";
    
                var words = str.Split(' ');
    
                if (words.Length <= numofwords)
                    return str;
    
                return string.Join(" ", words.Take(numofwords));
            }
        }
    }
    
    
  • Extension methods are only in scope when you explicitly import the namespace into your source code with a using directive. The "Shorten" extension method can be brought into scope with this "using ExtensionMethods;".
  • using ExtentionMethods;
    using System;
    
    namespace Example_ExtentionMethods
    {
        class Program
        {
            static void Main(string[] args)
            {
                string post = "This is supposed to be a very long post...";
                var shortenpost = post.Shorten(5);
                Console.WriteLine(shortenpost);
                Console.Read();
            }
        }
    }
    
    
  • At compile time, extension methods always have lower priority than instance methods defined in the type itself. In other words, if String class has an instance method "Shorten(int count)" and we have an extension method with the same signature for System namespace, the compiler will always bind to the instance method. In that case, our method will never be called.  

  • For those occasions when the original source isn't under our control, when a derived object is inappropriate or impossible, or when the functionality shouldn't be exposed beyond its applicable scope, Extension methods are an excellent choice.

  • When implement extension methods for a given type, should remember below points, 
    • An extension method will never be called if it has the same signature as a method defined in the type.
    • Extension methods are brought into scope at the namespace level. For example, if you have multiple static classes that contain extension methods in a single namespace named Extensions, they'll all be brought into scope by the using Extensions; directive.
References : udemy.com , docs.microsoft.com

Saturday, September 12, 2020

Events and Delegates

  • Events is a mechanism for communication between objects. When something happened to an object, It can notify other objects about that. 
  • Events are used to build a loosely couple application which classes and components are not tightly couple together. 
  • It helps to extend the application without breaking and changing the existing functionality. 
  • For an example, suppose we have a class  "VideoEncoder" which used to encode the video and send the email once video is encoded. In future, we might need to add another functionality  "send the text message" after the video is encoded. So then we have to add another functionality to send the messages. The problem is, we have to recompile the encoder class and all dependents of encoder class and redeploy. This is not a good idea. 

  • To solve this, we can use events. Here VideoEncoder is the publisher. mailService and messageService  are the subscribers. Video encoder does not know anything about the mailService and messageService. So in that case, in future if we need to add another subscriber , we can do it with minimal impact.  
       There are three main steps to implement above solution. 
  1. Define the delegate - Delegates works as a Agreement or contract between publisher and subscriber. It determines the signature of the event handler method in subscriber. 
  2. Define the Event based on that delegate.  
  3. Raise the event method which is protected ,virtual and void
    //By creating custom delegate and  EventArgs.Empty
        public class VideoEncoder
        {
            //1.Defines delegate
            //2.Defines a event based on event
            //3.raise the event
    
            public delegate void VideoEncodedEventHandler(object source, EventArgs args);
            public event VideoEncodedEventHandler VideoEncoded;
    
            public void Encode(Video video)
            {
                Console.WriteLine("Video Encoded");
                Thread.Sleep(3000);
    
                OnvideoEncoded();
            }
    
            protected virtual void OnvideoEncoded()
            {
                //VideoEncoded?.Invoke(this, EventArgs.Empty);
    
                if (VideoEncoded != null)
                {
                    VideoEncoded(this, EventArgs.Empty);
                }
    
            }
    
        }
    	
        class Program
        {
            static void Main(string[] args)
            {
                var video = new Video() { Name = "video1" };
                var videoEncoder = new VideoEncoder(); //publisher
                var mailService = new MailService();//Subscriber
                var messageService = new MessageService(); //Subscriber
    
                videoEncoder.VideoEncoded += mailService.OnVideoEncoded;
                videoEncoder.VideoEncoded += messageService.OnVideoEncoded;
                videoEncoder.Encode(video);
    	}
         }
    	
        public class MailService
        {
            public void OnVideoEncoded(object source, EventArgs args)
            {
                Console.WriteLine("Sending the email");
            }
        }
    	
    	public class MessageService
        {
            public void OnVideoEncoded(object source, EventArgs args)
            {
                Console.WriteLine("Sending the message");
            }
        }
        
        public class Video
        {
            public string Name { get; set; }
        }
    
  • Suppose we need to send addtional data (such as the video name which is encoded) to the subscriber. To do that, instead of EventsArgs we can use a custom class which derives from "EventArgs" class.
  •     //By creating custom  VideoEventArgs
        public class VideoEncoder
        {
            public delegate void VideoEncodedEventHandler(object source, VideoEventArgs args);
            public event VideoEncodedEventHandler VideoEncoded;
    
            public void Encode(Video video)
            {
                Console.WriteLine("Video Encoded");
                Thread.Sleep(3000);
    
                OnvideoEncoded(video);
            }
    
            protected virtual void OnvideoEncoded(Video video)
            {
                // VideoEncoded?.Invoke(this, new VideoEventArgs() { Video = video }); or
    
                if (VideoEncoded != null)
                {
                    VideoEncoded(this, new VideoEventArgs() { Video = video });
                }
    
            }
    
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                var video = new Video() { Name = "PickUpLimes" };
                var videoEncoder = new VideoEncoder(); //publisher
                var mailService = new MailService();//Subscriber
                var messageService = new MessageService(); //Subcriber
    
                videoEncoder.VideoEncoded += mailService.OnVideoEncoded;
                videoEncoder.VideoEncoded += messageService.OnVideoEncoded;
                videoEncoder.Encode(video);
                Console.Read();
            }
        }
    
        public class VideoEventArgs : EventArgs
        {
            public Video Video { get; set; }
        }
    
        public class MailService
        {
            public void OnVideoEncoded(object source, VideoEventArgs args)
            {
                Console.WriteLine("Sending the email. Video name is " + args.Video.Name);
            }
        }
    
        public class MessageService
        {
            public void OnVideoEncoded(object source, VideoEventArgs args)
            {
                Console.WriteLine("Sending the message. Video name is " + args.Video.Name);
            }
        }
    
        public class Video
        {
            public string Name { get; set; }
        }
    
  • In .Net , same thing can be achieved using in-built EventHandler delegate instead of creating the custom delegate. EventHandler comes in two forms. One is normal form EventHandler  and other one is generic form EventHandler<T> . If we need to pass the data, we can use generic version. If not , can use the normal form.   
  •  	
        //using EventHandler delegate instead of custom delegate
        public class VideoEncoder
        {
            //Generic Form
            public event EventHandler<VideoEventArgs> VideoEncoded;
    
            //Normal Form
           // public event EventHandler VideoEncoded; 
    
            public void Encode(Video video)
            {
                Console.WriteLine("Video Encoded");
                Thread.Sleep(3000);
    
                OnvideoEncoded(video);
            }
    
            protected virtual void OnvideoEncoded(Video video)
            {
                //VideoEncoded?.Invoke(this, EventArgs.Empty);
    
                if (VideoEncoded != null)
                {
                    VideoEncoded(this, new VideoEventArgs() { Video = video });
                }
    
            }
    
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                var video = new Video() { Name = "PickUpLimes" };
                var videoEncoder = new VideoEncoder(); //publisher
                var mailService = new MailService();//Subscriber
                var messageService = new MessageService(); //Subcriber
    
                videoEncoder.VideoEncoded += mailService.OnVideoEncoded;
                videoEncoder.VideoEncoded += messageService.OnVideoEncoded;
                videoEncoder.Encode(video);
                Console.Read();
            }
        }
    
        public class VideoEventArgs : EventArgs
        {
            public Video Video { get; set; }
        }
    
        public class MailService
        {
            public void OnVideoEncoded(object source, VideoEventArgs args)
            {
                Console.WriteLine("Sending the email. Video name is " + args.Video.Name);
            }
        }
    
        public class MessageService
        {
            public void OnVideoEncoded(object source, VideoEventArgs args)
            {
                Console.WriteLine("Sending the message. Video name is " + args.Video.Name);
            }
        }
    
        public class Video
        {
            public string Name { get; set; }
        }
    

 References : Udemy.com

Friday, September 11, 2020

Lambda Expression

  • It is an anonymous method which has no access modifier, no name and  no return statement. 
(input-parameters) => expression
  • We can write lambda expression to achieve something with less code. Below example shows how we can write a code to get multiplication of two numbers with lambda expression and without lambda expression. 
  •     class Program
        {
            static void Main(string[] args)
            {
                //args => expression
    
                //Without Lambda Expression
                Console.WriteLine(Square(5));
    
                //With Lambda Expression and Func
                Func<int, int> multiplication = number => number * number;
                Console.WriteLine(multiplication(5));
    
                Console.Read();
            }
    		
    	private static int Square(int x)
            {
                return x * x;
            }
        }
    	
    
  • We can also use lambda expressions when we write LINQ in C#.
  • int[] numbers = { 2, 3, 4, 5 };
    var squaredNumbers = numbers.Select(x => x * x);
    Console.WriteLine(string.Join(" ", squaredNumbers));
    // Output:
    // 4 9 16 25
    
    //Consider new BookRepository().GetBooks() returns list of books
    var listofBooks = new BookRepository().GetBooks();
    List<Books> cheapBooks = listofBooks.FindAll(b => b.price < 20).ToList();
    	
    

Thursday, September 10, 2020

Delegates

  • Delegate is an object that knows how to call a method or a  group of methods which have the same signature. 
  • It is a reference to a function.
  • Of course, we can call methods directly, but we need delegates for designing extensible and flexible applications. (Ex: Frameworks).
  • Imagine that you are designing a framework which is use for processing the photos. In that framework, you have defined few photo processing ways such as "Apply Brightness" , "Apply Contrast" and etc. In future, may be a client who is using your framework need to add their own photo filter which we haven't defined. So in that case, we have to change our application , recompile and redeploy. It is not a good idea. If we use delegates in our frameworks, client can add any no of filters without relying on us. See below example. 
  •     public class Photo
        {
            public Photo Load(string path)
            {
                return new Photo();
            }
        }
    	
        public class Filter
        {
            public void Resize(Photo photo)
            {
                Console.WriteLine("Changed the Size");
            }
    
            public void ChangeBrightness(Photo photo)
            {
                Console.WriteLine("Changed the brightness");
            }
    
            public void ChangeContrast(Photo photo)
            {
                Console.WriteLine("Changed contrast of the photo");
            }
    
        }
    	
        public class PhotoMaker
        {
            // Define the delegate
            public delegate void PhotoFilterHandler(Photo photo);
            public void Process(string path, PhotoFilterHandler photofilterhandler )
            {
                var photoObject = new Photo();
                var photo = photoObject.Load(path);
                photofilterhandler(photo);
            }
        }
    	
        class Program
        {
            static void Main(string[] args)
            {
                var photomaker = new PhotoMaker();
                var filter = new Filter();
    			
    	    // Adding ChangeBrightness filter
                PhotoMaker.PhotoFilterHandler filterhandler = filter.ChangeBrightness;
    			
    	    //Adding ChangeContrast filter
    	    filterhandler += filter.ChangeContrast;
    			
    	    // Remove ChangeBrightness filter
                filterhandler -= filter.ChangeBrightness;
    			
    	    //Adding custom method  without changing the PhotoProcess class
                filterhandler+= RemoveRedEye;
               
    	    photomaker.Process("", filterhandler);	
    
                Console.Read();
            }
    
            static void RemoveRedEye(Photo photo)
            {
                Console.WriteLine("Remove Red Eye");
            }
        }
    	
    
  • In .Net, there are two delegates which are generic. They are Action and Func. Difference between Func and Action is Func point to a method that has a return value and Action point to a method that returns void (no return type). 

  • Below code uses in built Action delegate instead of creating a custom delegate. 
  •  	
    public class Photo
        {
            public Photo Load(string path)
            {
                return new Photo();
            }
        }
    	
        public class Filter
        {
            public void Resize(Photo photo)
            {
                Console.WriteLine("Changed the Size");
            }
    
            public void ChangeBrightness(Photo photo)
            {
                Console.WriteLine("Changed the brightness");
            }
    
            public void ChangeContrast(Photo photo)
            {
                Console.WriteLine("Changed contrast of the photo");
            }
        }
    	
        public class PhotoMaker
        {
            public void Process(string path, Action<Photo> photofilterhandler )
            {
                var photoObject = new Photo();
                var photo = photoObject.Load(path);
                photofilterhandler(photo);
            }
        }
    	
        class Program
        {
            static void Main(string[] args)
            {
                var photomaker = new PhotoMaker();
                var filter = new Filter();
    			
                // Adding ChangeBrightness filter
                Action<Photo> filterhandler = filter.ChangeBrightness;
    			
    	    //Adding ChangeContrast filter
    	    filterhandler += filter.ChangeContrast;
    			
    	    // Remove ChangeBrightness filter
                filterhandler -= filter.ChangeBrightness;
    			
    	    photomaker.Process("", filterhandler);	
    
                Console.Read();
            }
        }

  • Use a delegate in the following circumstances:
      • An eventing design pattern is used.
      • The caller has no need to access other properties, methods, or interfaces on the object implementing the method.

      Monday, September 7, 2020

      Generics

      • Generic classes and methods combine reusability, type safety, and efficiency in a way that their non-generic counterparts cannot.
      • Generics introduce the concept of type parameters to .NET, which make it possible to design classes and methods that defer the specification of one or more types until the class or method is declared and instantiated by client code.
      • For example, by using a generic type parameter T, you can write a single class that other client code can use without incurring the cost or risk of runtime casts or boxing operations, as shown here:
      •     public class GenericList<T>
            {
                public void Print(T key)
                {
                    Console.WriteLine(key);
                }
        
            }
        	
           class TestGenericList
           {
            static void Main()
            {
               // Type of T is int
                var genericnumbers = new GenericList<int> ();
                genericnumbers.Print(5);
        
        	// Type of T is strings
                var genericStrings = new GenericList<strings>();
                genericStrings.Print("Janaki");
            }
        }
        	
        
      • The System.Collections.Generic namespace contains several generic-based collection classes.We can also create custom generic types and methods to provide your own generalized solutions and design patterns that are type-safe and efficient.
      Constraints on Type Parameters

      • Constraints specify the capabilities and expectations of a type parameter.
      • Without any constraints, the type argument could be any type. The compiler can only assume the members of System.Object, which is the ultimate base class for any .NET type.
      • If client code uses a type that doesn't satisfy a constraint, the compiler issues an error. 
      • Constraints are specified by using the where contextual keyword. Below are some examples. 
        • where T : struct -  The type argument must be a non-nullable value type. 
        • where T : class -  T must be a non-nullable reference type.
        • where T: <any base class> :  T must be a non-nullable reference type derived from the specified base class.  
        •     public class CalculatePrice<T> where TProduct : Product
              {
                  public decimal getPrice(TProduct product)
                  {
                      return product.price;
                  }
              }
              public class Product
              {
                  public decimal price { get; set; }
              }
          	
          
        • where T : <interface name> - The type argument must be or implement the specified interface. Multiple interface constraints can be specified. The constraining interface can also be generic.  
        • where T : new() - T is an object type that has a default constructor. 
        •     public class CalculatePrice<T> where TProduct : new()
              {
                  public void DoSomeThing()
                  {
                      var Onj = new T();
                  }
               }
          

      • Type parameters that have no constraints can not use !=, > ,== operators because there's no guarantee that the concrete type argument will support these operators.
      •     public class Utilities<T> where T :IComparable
            {
                public int Max(int a, int b)
                {
                    return a > b ? a : b;
                }
        
                public T Max (T a, T b)
                {
                    //Can not compare by using operators a>b
                    return a.CompareTo(b)>0 ? a : b;
                }
        
            }
        	
        
      References :  docs.microsoft.com and udemy.com

      Thursday, September 3, 2020

      Interfaces

      • Interface contains declaration of methods, properties, events and indexers. 
      • public interface ITaxCalculator
        {
         int Calculate();
        }
        
      • Members of an interface do not have access modifiers and can not declare variables in the interface because fields are about the implementation details. 
      • Interfaces help building loosely coupled applications. We reduce the coupling between two classes by putting an interface between them. This way, if one of these classes changes, it will have no impact on the class that is dependent on that (as long as the interface is kept the same).
      Interface and Testability
      • In order to unit test a class, we need to isolate it. This means: we need to assume that every other class in our application is working properly and see if the class under test is working as expected. But in below example, OrderProcessor class is depended on the ShippingCalculator class because of "CalculateShipping" method in "Process" method.
      •     public class Shipment
            {
                public DateTime shippingdate;
                public object cost { get; set; }
            }
        
            public class Order
            {
                public Shipment Shipment;
                public bool IsShipped { get { return Shipment != null; }}
                public DateTime DatePlaced { get; set; }
                public float TotalProce { get; set; }
            }
        
            class Program
            {
                static void Main(string[] args)
                {
                    var orderprocessor = new OrderProcessor();
                    var order = new Order { DatePlaced = DateTime.Now, TotalProce = 100f };
                    orderprocessor.Process(order); 
                }
            }
        	
            public class OrderProcessor
             {
                private readonly ShippingCalculator _shippingCalculator;
        
                public OrderProcessor()
                {
                    _shippingCalculator = new ShippingCalculator();
                }
        
                public void Process(Order order)
                {
                    if (order.IsShipped)
                    {
                        throw new InvalidOperationException("The order already is shipped");
                    }
        
                    order.Shipment = new Shipment
                    {
        		//Depend on the ShippingCalculator class
                        cost = _shippingCalculator.CalculateShipping(order),
                        shippingdate = DateTime.Now.AddDays(1)
                    };
                }
            }
        	
            public class ShippingCalculator
            {
                public float CalculateShipping(Order order)
                {
                    if (order.TotalProce > 30f)
                    {
                        return order.TotalProce * 0.01f;
                    }
                    return 0;
                }
            }
        	
        
      • A class that has tight dependencies to other classes cannot be isolated. To solve this problem, we should use an interface. (The changes are in bold)
      •   public class Shipment
            {
                public DateTime shippingdate;
                public object cost { get; set; }
            }
        
            public class Order
            {
                public Shipment Shipment;
                public bool IsShipped { get { return Shipment != null; }}
                public DateTime DatePlaced { get; set; }
                public float TotalProce { get; set; }
            }
        
            class Program
            {
                static void Main(string[] args)
                {
                    var orderprocessor = new OrderProcessor(new ShippingCalculator());
                    var order = new Order { DatePlaced = DateTime.Now, TotalProce = 100f };
                    orderprocessor.Process(order);
                    Console.Read();  
                }
            }
        	
            public class OrderProcessor
            {
                private readonly IShippingCalculator _shippingCalculator;
        
                public OrderProcessor(IShippingCalculator calculator)
                {
                    _shippingCalculator = calculator;
                }
        
                public void Process(Order order)
                {
                    if (order.IsShipped)
                    {
                        throw new InvalidOperationException("The order already is shipped");
                    }
        
                    order.Shipment = new Shipment
                    {
                        cost = _shippingCalculator.CalculateShipping(order),
                        shippingdate = DateTime.Now.AddDays(1)
                    };
                }
            }
        	
            public interface IShippingCalculator
            {
                float CalculateShipping(Order order);
            }
        	
            public class ShippingCalculator : IShippingCalculator
            {
                public float CalculateShipping(Order order)
                {
                    if (order.TotalProce > 30f)
                    {
                        return order.TotalProce * 0.01f;
                    }
                    return 0;
                }
            }
      Interfaces and Extensibility
      • We can use interfaces to change our application’s behaviour by “extending” its code(rather than changing the existing code).
      • If a class is dependent on an interface, we can supply a different implementation of that interface at runtime. This way, the behaviour of the application changes without any impact on that class.
      • For example, let’s assume our DbMigrator class is dependent on an ILoggerinterface. At runtime, we can supply a ConsoleLogger to log the messages on the console. Later, we may decide to log the messages in a file (or a database). We can simply create a new class that implements the ILogger interface and inject it into DbMigrator.
      • 
            public interface ILogger
            {
                void LogInfo(string message);
                void LogError(string message);
            }
            
        	public class DBMigrator
            {
                private readonly ILogger _logger;
        
                public DBMigrator(ILogger logger)
                {
                    _logger = logger;
                }
        
                public void Migrate()
                {
                    _logger.LogError("DBMigrating started at " + DateTime.Now);
                    _logger.LogInfo("DBMigrating ended at " + DateTime.Now);
                }
            }
        
            public class ConsoleLogger : ILogger
            {
                public void LogError(string message)
                {
                    Console.WriteLine(message);
                }
        
                public void LogInfo(string message)
                {
                    Console.WriteLine(message);
                }
            }
        
        
            public class FileLogger : ILogger
            {
                public void LogError(string message)
                {
                    //Here should write the code to insert the log error in to file
                    Console.WriteLine(message);
                }
        
                public void LogInfo(string message)
                {
                    //Here should write the code to insert the loginfo in to file
                    Console.WriteLine(message);
                }
            }
        	
        
      References : Udemy.com

      Wednesday, September 2, 2020

      Sealed Classes and Members

      • If "sealed" modifier applied to a class, prevents derivation from that class.
      • If "sealed" modifier applied to a method, prevents overriding of that method in a derived class.  
      • Sealed classes are slightly faster because of some run time optimization.  But sealed classes are hardly ever used. 
      • The string class is declared as sealed, and that’s why we cannot inherit from it


      Abstract Classes and Members

      •  Abstract modifier used to indicate that a class or member is missing the implementation. 
      • The purpose of having a abstract class to provides a common definition of a base class that multiple derived classes can be shared.
      • We use abstract members when it doesn’t make sense to implement them in a base class. For example, the concept of drawing a shape is too abstract. We don’t know how to draw a shape. This needs to be implemented in the derived classes.
      •     public class Shape
            {
                public virtual void Draw()
                {
                }
            }
        
            public class Circle : Shape
            {
                public override void Draw()
                {
                    Console.WriteLine("Drawing a circle");
                }
            }
        
        
      • In these situations, better approach is to use abstract modifier. In a derived class, we need to override all abstract members of the base class, otherwise that derived class is going to be abstract too.  
      •     public abstract class Shape
            {
                public abstract int Weight { get; set; }
                public abstract void Draw();
        		
                //Concrete Method
                public void Print()
                {
                }
        
            public class Circle : Shape
            {
                private int _weight;
                public override int Weight
                {
                    get
                    {
                        return _weight;
                    }
        
                    set
                    {
                        Weight = _weight;
                    }
                }
        
                public override void Draw()
                {
                    Console.WriteLine("Drawing a circle");
                }
            }
        
      • When a class member is declared as abstract, that class needs to be declared as abstract as well. That means that class is not complete.
      • We can not define abstract variables and abstract class cannot be instantiated. 
      • In C#, "Stream" class is an abstract class and because it is too abstract. But FileStream is derived from System.IO.Stream and it is very specific. It allows to read and write data to file. 



      Tuesday, September 1, 2020

      Polymorphism

       Polymorphism means ability to have many forms. There are two types pf polymorphism. 

      1. Compile time polymorphism/Overloading
      2. Runtime polymorphism/Overriding
      Overloading

      • Compile time polymorphism is method and operators overloading. It is also called early binding.
      • In method overloading method performs the different task at the different type and different no of input parameters with the same method name.
      • You should consider overloading a method when you need a couple of methods for some reason that take different parameters, but conceptually do the same thing.
      •     class Program  
            {  
                public class Shape  
                {  
                    public void Area(float r)  
                    {  
                        float a = (float)3.14 * r;  
                        // Function overload with 1 parameter.  
                        Console.WriteLine("Area of a circle: {0}",a);  
                    }  
                    public void Area(float l, float b)  
                    {  
                        float x = (float)l* b;  
                        // Function overload with 2 parameters.  
        Console.WriteLine("Area of a rectangle: {0}",x); } public void Area(float a, float b, float c) { float s = (float)(a*b*c)/2;
        // Function overload with 3 parameters.
        Console.WriteLine("Area of a circle: {0}", s); } } static void Main(string[] args) { Shape shape= new Shape(); shape.Area(2.0f);
        shape.Area(20.0f,30.0f);
        shape.Area(2.0f,3.0f,4.0f);
        Console.ReadLine(); } }

      Overriding
      • Method overriding means changing the implementation of an inherited method.
      • If a declare a method as virtual in the base class, we can override it in a derived class.
      • At run-time, when client code calls the method, the CLR looks up the run-time type of the object, and invokes that override of the virtual method. 
      • In the source code you can call a method on a base class, and cause a derived class's version of the method to be executed.
      • Virtual methods enable you to work with groups of related objects in a uniform way. For example, suppose you have a drawing application that enables a user to create various kinds of shapes on a drawing surface. Even though this can be  achieved by no of switch statements, it will be hard to maintenance. So you can achieve the same thing by using overriding a method.
      •     public class Shape
            {
                public int X { get; private set; }
                public int Y { get; private set; }
                public int Height { get; set; }
                public int Width { get; set; }
        
                // Virtual method
                public virtual void Draw()
                {
                    Console.WriteLine("Performing base class drawing tasks");
                }
            }
        
            public class Circle : Shape
            {
                //Override Method
                public override void Draw()
                {
                    // Code to draw a circle...
                    Console.WriteLine("Drawing a circle");
                }
            }
            public class Rectangle : Shape
            {
                public override void Draw()
                {
                    // Code to draw a rectangle...
                    Console.WriteLine("Drawing a rectangle");
                }
            }
            public class Triangle : Shape
            {
                public override void Draw()
                {
                    // Code to draw a triangle...
                    Console.WriteLine("Drawing a triangle");
                }
            }
        
            public class Program
            {
                static void Main(string[] args)
                {
                    var shapes = new List
                                {
                                 new Rectangle(),
                                 new Triangle(),
                                 new Circle()
                                };
        
                    // invoked Draw() on each of the derived classes, not the base class.
                    foreach (var shape in shapes)
                    {
                        shape.Draw();
                    }
                    Console.Read();
                }
            }
            
            Output
            Drawing a rectangle
            Drawing a triangle
            Drawing a circle
        	
        
      • A derived class is able to stop virtual inheritance by declaring an override member as "sealed".
      •     public class Triangle : Shape
            {
                public sealed void Draw()
                {
                    // Code to draw a triangle...
                    Console.WriteLine("Drawing a triangle");
                }
            }
        
      • Using the "base" keyword, the derived class is able to access the method.
      •     public class Triangle : Shape
            {
                public override void Draw()
                {
        	   base.Draw(); 
                }
            }

      Saturday, August 29, 2020

      Reference Types and Value Types

      Value Types

      • Value type are the variables which are stored in its own memory location.
      • Value types are stored in stack according to the order it is created.
      Only c will be changed to 7.


      Reference Types 

      • Reference types does not stored its value within its own memory location. Instead of that , it stores a pointer/address/reference where the actual value is stored.
      • Reference types are stored in heap. But the variable is stored in stack and data is stored on the heap. 

      Both d.hp and f.hp will be changed to 100.

       



      Tuesday, August 25, 2020

      Upcasting and Downcasting

      •  Upcasting: conversion from a derived class to a base class
      •  All objects can be implicitly converted to a base class reference.  
      •       Shape shape = circle;   // Shape is base class and circle is derived class	
        
      • Downcasting: conversion from a base class to a derived class 
      • Downcasting requires a cast.
      •       Circle circle= circle;   // Shape is base class and circle is derived class	
      • Casting can throw an exception if the conversion is not successful. We can use the as keyword to prevent this. If conversion is not successful, null is returned. 
      •       Circle circle = shape as Circle;
              if (circle != null)
      • We can also use the is keyword
      • if (shape is Circle) {
        var circle = (Circle) shape;
        }

      Access Modifiers

      •  In C# we have 5 access modifiers: 
        • Public
        • Private
        • Protected
        • Internal
        • Protected Internal
      • A class member declared with public is accessible everywhere. 
      • A class member declared with private is accessible only from inside the class.
      • A class member declared with protected is accessible for containing class and the derived types of the containing class. 
      • A class member declared with internal is accessible only for current assembly.
      • A class member declared with protected internal is accessible for current assembly and derived types of the containing class.

      Monday, August 24, 2020

      Properties

      •  A property is a class member that encapsulate a getter/setter for accessing a filed.  
      • As a best practice, we must declare fields as private and create public properties to provide access to them. 
      • A property encapsulates a get and a set method.
      •     public class Customer
            {
                private string _name;
                public string Name
                {
                    get { return _name; }
                    set { _name = value; }
                }
            }
        
      • Inside the get/set methods we can have some logic.
      •     public class Person
            {
                public DateTime BirthDate { get; set; }
                public int Age
                {
                    get
                    {
                        var timespan = DateTime.Today - BirthDate;
                        var years = timespan.Days / 365;
                        return years;
                    }
                }
            }
        
      • If you don’t need to write any specific logic in the get or set method, it’s more efficient to create an auto-implemented property. An auto-implemented property encapsulates a private field behind the scene. So you don’t need to manually create one. The compiler creates one for you.
      •     public class Person
            {
                public DateTime BirthDate { get; set; }
            }
        
      • Auto-implemented properties are required to specify both get and set, so if you want an auto-implemented property to be read-only, you must use private setters. 
      •     public class Person
            {
                public DateTime BirthDate { get; private set; }
            }
        

      Friday, August 21, 2020

      Read only and Constants Fields

      Readonly
      • When a field is declared with readonly, it needs to be initialized either during declaration or in a constructor.
      •  
            public class Const_V_Readonly
            {
                public readonly int Readonly_Value;
        
                public Const_V_Readonly()
                {
                    Readonly_Value = 3;  
                }
            }
        
      • A value can be assigned only once to readonly fileds.
      • We use the readonly modifier to improve the robustness of our code. It prevents from accidentally overwriting the value of a field, which can result in an unexpected state.
      • When use static modifier for the readonly fields, it needs to be initialized either during declaration or in a static constructor. 
      •  
            public class Const_V_Readonly
            {
                public static readonly int Readonly_Value;
        
        	//Access modifiers are not allowed on static constructors
                static Const_V_Readonly()
                {
                    Readonly_Value = 3;
                }
            }
      • If consider "Const_V_Readonly" class in AssemblyA , AssemblyB references AssemblyA and uses these values in code. When AssemblyA is compiled, readonly values are like a ref to a memory location. The value is not baked into AssemblyB's IL. This means that if the memory location is updated, AssemblyB gets the new value without recompilation. So if "Readonly_Value" is updated to 30, you only need to build AssemblyA. All clients do not need to be recompiled. 
      • So if you have a constant that may change or when in doubt, use a readonly.


      Constants 
      • A const keyword is used to declare constant fields and constant local.
      • The value of the constant field is the same throughout the program or in other words, once the constant field is assigned the value of this field is not be changed. 
            public class Const_V_Readonly
            {
                public const int Constant_Value = 2;
            }
      • The constant field should be initialized on the declaration. (Can not intialize it in a constructor or method)
      • If consider "Const_V_Readonly" class in AssemblyA and AssemblyB references AssemblyA and uses these values in code. When AssemblyA is compiled,  const value is like a find-replace, the value 2 is 'baked into' the AssemblyB's IL. This means that if we update Constant_Value to 20 in the future. AssemblyB would still have 2 till we recompile it.
      • So if you are confident that the value of the constant won't change use a const.

      Wednesday, August 19, 2020

      Constructors

      •  Constructor is a method that is called when an instance of a class is created. 
      •  Usage of a constructor is to put an object in an early state (To initialize some of the class fields in a class). 
      •  Constructor can be declared as below.
            public class Customer
            {
               //Default Constructor
                public Customer()
                {
        
                }
            }

      • If we don't define a default constructor or parameterless constructor, C# compiler automatically will create it when an instance of a class is created. 
            public class Customer
            {
        	public bool IsMarried;
        	public string Age;
            }
        
            class Program
            {
                static void Main(string[] args)
                {
                    var customer = new Customer();
                    Console.WriteLine(customer.IsMarried);
                    Console.WriteLine(customer.Age);
                    Console.Read();
                }
            }
        	
        	Output
        	False
        	0

      • We can also define a constructor with one or more parameter which is called parameter constructor.
            public class Customer
            {
        
        public string Name;
        //Parameter Constructor public Customer(string name) { this.Name = name; } }

      • Constructors can be overloaded. Overloading means creating a method with the same name and different signatures. Signature is what uniquely identify a method. That includes return type, name, parameter type , no of input parameters and order of the parameters.
            public class Customer
            {
                public Customer(){}
                public Customer(string name){}
                public Customer(string name, int Age){}
            }
      • As a best practice, when we have a list of objects inside a class, always the list should be initialized in the constructor or on the declaration. Otherwise it will give an exception.
            public class Order
            {
            }
        
            public class Customer
            {
                public string Name;
                public int Age;
                public List<Orders>;
        
                public Customer()
                {
                }
                public Customer(string name) 
                {
                    this.Name = name;
                }
                public Customer(string name, int age)
                {
                    this.Name = name;
                    this.Age = age;
                }
            }
        
            class Program
            {
                static void Main(string[] args)
                {
                    var customer = new Customer();
                    var order = new Order();
                    customer.orders.Add(order);
                    Console.Read();
                }
            }

      • So we should initialize the list of order inside the constructor. But the problem is, when we use other parameter constructors , list will be set to null again. To overcome this, We can pass control from one constructor to the other by using the this keyword.
            public class Customer
            {
                public string Name;
                public int Age;
                public List orders;
        
                public Customer()
                {
                    orders = new List();
                }
                public Customer(string name) :this()
                {
                    this.Name = name;
                }
                public Customer(string name, int age) : this(name)
                {
                    this.Name = name;
                    this.Age = age;
                }
            }
      • But still this way is little ugly and hard to maintain. So you should only define a constructor when you really have to initialize some fields and etc. 
      Constructors Inheritance

      • When creating an object of a type that is part of an inheritance hierarchy, base class constructors are always executed first. They are not inherited to the derived class and need to define explicitly. 
      •  
            public class Vehicle
            {
                public Vehicle()
                {
                    Console.WriteLine("Vehicle is being initialized..");
                }
            }
        
            public class Car : Vehicle
            {
                public Car()
                {
                    Console.WriteLine("Car is being initialized..");
                }
            }
        
            public class Program
            {
                static void Main(string[] args)
                {
                    var obj = new Car();
                    Console.Read();
                }
            }
            
            	
        
        OutPut
        Vehicle is being initialized..
        Car is being initialized..
      • We can use the base keyword to pass control to a base class constructor.
      •  
            public class Vehicle
            {
                private readonly string _registrationNumber;
        
                public Vehicle(string registrationNumber)
                {
                    this._registrationNumber = registrationNumber;
                    Console.WriteLine("Vahicle is being initialized.. Registration No : " + registrationNumber);
        } } public class Car : Vehicle { public Car(string registrationNumber) :base(registrationNumber) { Console.WriteLine("Car is being initialized.. Registration No : "+ registrationNumber); } } public class Program { static void Main(string[] args) { var obj = new Car("CAS-5276"); Console.Read(); } } OutPut Vahicle is being initialized.. Registration No : CAS-5276
        Car is being initialized.. Registration No : CAS-5276