Tuesday, September 14, 2021

C# advanced interview questions for experienced - Part 2

Delegates in c# with example

·         Delegates are type-safe function pointers. It holds a reference(pointer) to the function.

·         The signature of the delegate must match the signature of the function, the delegates points to, otherwise, you get a compiler error.

·         A delegate is similar to a class. You can create an instance of it, and when you do so, you pass the function name as a parameter to the delegate constructor, and this function the delegate will point to.

A Delegate is a reference type variable that holds the reference to a method. The reference can be changed at runtime.

D Delegates are especially used for implementing events and call-back methods. All delegates are implicitly derived from the “System. Delegate” class.

·         Delegates allow methods to be passed as parameters.

·         Delegates can be used to define callback methods.

·         Delegates can be chained together; for example, multiple methods can be called on a single event.

 

There are three types of delegates that can be used in C#.

·         Single Delegate

·         Multicast Delegate

·         Generic Delegate

 

Single Delegate: Single delegate can be used to invoke a single method.

Multicast Delegate

The delegate can point to multiple methods. A delegate that points multiple methods is called a multicast delegate. The "+" or "+=" operator adds a function to the invocation list, and the "-" and "-=" operator removes it.

Generic Delegate:

Generic Delegate was introduced in .NET 3.5 that don't require to define the delegate instance in order to invoke the methods.

There are three types of generic delegates:

·         Func

·         Action

·         Predicate

 

Ex of delegate:

   public delegate void Hellofunctiondelegate(string message);

    class Program

    {

        static void Main()

        {

            Hellofunctiondelegate del = new Hellofunctiondelegate(Hello);

            del("Hello from delegate");

        }

        public static void Hello(string strmsgg)

        {

            Console.WriteLine(strmsgg);

        }

    }

 


 

-----------------------------------------------------------------------------------------------------------------------------
What is Multithreading in c#?

Multi-threading is a process that contains multiple threads within a single process. Here each thread performs different activities.

Multitasking is the simultaneous execution of multiple tasks or processes over a certain time interval. Windows operating system is an example of multitasking because it is capable of running more than one process at a time like running Google Chrome, Notepad, VLC player, etc. at the same time. The operating system uses a term known as a process to execute all these applications at the same time. A process is a part of an operating system that is responsible for executing an application. Every program that executes on your system is a process and to run the code inside the application a process uses a term known as a thread.

A thread is a lightweight process, or in other words, a thread is a unit which executes the code under the program. So every program has logic and a thread is responsible for executing this logic. Every program by default carries one thread to executes the logic of the program and the thread is known as the main thread.This single-threaded model has a drawback. The single thread runs all the process present in the program in synchronizing manner, means one after another. So, the second process waits until the first process completes its execution, it consumes more time in processing.

 

 

Multi-tasking:

Multi-threading is a process that contains multiple threads within a single process. Here each thread performs different activities. For example, we have a class and this call contains two different methods, now using multithreading each method is executed by a separate thread. So the major advantage of multithreading is it works simultaneously, which means multiple tasks execute at the same time. And also maximizing the utilization of the CPU because multithreading works on time-sharing concept mean each thread takes its own time for execution and does not affect the execution of another thread, this time interval is given by the operating system.’’

Ex:Multi-tasking:

Method 1(In-progress)->Method 2 (Resume after method1)

Ex:Multi-threading:

Method 1(In-progress) -> Method2(In-progress)

 

Following are the various states in the life cycle of a thread −

·        The Unstarted State − It is the situation when the instance of the thread is created but the Start method is not called.

·        The Ready State − It is the situation when the thread is ready to run and waiting CPU cycle.

·        The Not Runnable State − A thread is not executable, when

    • Sleep method has been called
    • Wait method has been called
    • Blocked by I/O operations

·        The Dead State − It is the situation when the thread completes execution or is aborted.


Properties/Methods:

 

CurrentContext, CurrentCulture, CurrentPrinciple, CurrentThread, CurrentUICulture, ExecutionContext, IsAlive, IsBackground, ManagedThreadId, Name, Priority, ThreadState

 --------------------------------------------------------------------------------------------------------------------------

What are Events?

An event is a notification that some action has occurred. Delegates and events are related because an event is built upon a delegate. Both expand the set of programming tasks to which C# can be applied. It is an important C# feature is built upon the foundation of delegates: the event. An event is, essentially, an automatic notification that some action has occurred. Events work like this:

An object that has an interest in an event registers an event handler for that event. When the event occurs, all registered handlers are called. Event handlers are represented by delegates.

 Events are members of a class and are declared using the event keyword. Its most commonly used form is shown here:

event event-delegate event-name;

 Here, event-delegate is the name of the delegate used to support the event, and event-name is the name of the specific event object being declared. 
 --------------------------------------------------------------------------------------------------------------------------

What is Reflection in C#? 

Reflection objects are used for obtaining type information at runtime. The classes that give access to the metadata of a running program are in the System. Reflection namespace. In C#, reflection is a process to get metadata of a type at runtime.

Reflection is when managed code can read its own metadata to find assemblies. Essentially, it allows code to inspect other code within the same system.

Reflection provides objects (of type Type) that describe assemblies, modules, and types. You can use reflection to dynamically create an instance of a type, bind the type to an existing object, or get the type from an existing object and invoke its methods or access its fields and properties

It contains classes that allow you to obtain information about the application and to dynamically add types, values, and objects to the application.

With reflection in C#, you can dynamically create an instance of a type and bind that type to an existing object. Moreover, you can get the type from an existing object and access its properties. When you use attributes in your code, reflection gives you access as it provides objects of Type that describe modules, assemblies, and types.

To understand reflection, there are a few basics you should understand about modules, types, and members:

·         Assemblies contain modules

·         Modules contain types

·         Types contain members

 Reflection is the process of describing the metadata of types, methods and fields in a code. It  enables you to obtain data about the loaded assemblies, the elements within them like classes, methods and value types. Some of the commonly used classes of System.Reflection are:

Class

Description

Assembly

describes an assembly which is a reusable, versionable, and self-describing building block of a common language runtime application

AssemblyName

Identifies an assembly ith a unique name

ConstructorInfo

Describes a class constructor and gives access to the metadata

MethodInfo

Describes the class method and gives access to its metadata

ParameterInfo

Describes the parameters of a method and gives access to its metadata

EventInfo

Describes the event info and gives accessto its metadata

PropertyInfo

Discovers the attributes of a property and provides access to property metadata

MemberInfo

Obtains information about the attributes of a member and provides access to member metadata

 

// Using GetType to obtain type information:

int i = 42;

System.Type type = i.GetType();

System.Console.WriteLine(type);

O/P:

System.Int32

// create instance of class DateTime

DateTime dateTime = (DateTime)Activator.CreateInstance(typeof(DateTime));

 


The System.Type class is the main class for the .NET Reflection functionality to access metadata. The System.Type class is an abstract class and represents a type in the Common Type System (CLS). It represents type declarations: class types, interface types, array types, value types, enumeration types, type parameters, generic type definitions, and open or closed constructed generic types.

 The Type class and its members are used to get information about a type declaration and its members such as constructors, methods, fields, properties, and events of a class, as well as the module and the assembly in which the class is deployed.

 







----------------------------------------------------------------------------------------------------------------------

What is Anonymous Types in C#?

 

·         Anonymous types in C# are the types which do not have a name or you can say the creation of new types without defining them.

·         It is introduced in C# 3.0. 

·         In C#, an anonymous type is a type (class) without any name that can contain public read-only properties only. It cannot contain other members, such as fields, methods, events, etc.

·         The "type" of the type is decided by the compiler. 

·         C# allows you to create an object with the new keyword without defining its class.

·         Anonymous types are class type, directly derived from “System. Object” so they are reference types.

·         If two or more Anonymous types have the same properties in the same order in the same assembly then the compiler treats them as the same type.

·         All properties of anonymous types are read-only.

·         LINQ query expressions, and lambdas commonly use anonmous types. Anonymous types are used with the "Select" clause of LINQ query expression to return records.

·         The scope of the anonymous type is always limited to the method in which they are defined. Due to their local scope, you are not allowed to pass an anonymous type to another method, but you can pass it to those methods which can accept dynamic type parameters.

 

Example: Anonymous Type

var student = new { Id = 1, FirstName = "James", LastName = "Bond" };

 

 

The properties of anonymous types are read-only and cannot be initialized with a null, anonymous function, or a pointer type. The properties can be accessed using dot (.) notation, same as object properties. However, you cannot change the values of properties as they are read-only.

 

An anonymous type's property can include another anonymous type.

You can create an array of anonymous types also.

Anonymous types have nothing to do with the design of systems or even at the class level. They're a tool for developers to use when coding. These are handy when you create types for "use and throw" purposes. You would not need to declare a class or a struct for every time you need a temporary type.

-----------------------------------------------------------------------------------------------------------------------------

What is Serialization in C#?

 

Serialization is the process of converting an object into a stream of bytes to store the object or transmit it to memory, a database, or a file. Its main purpose is to save the state of an object in order to be able to recreate it when needed. The reverse process is called deserialization.

Following namespaces are involved in serialization process,

  • System.Runtime.Serialization
  • System.Runtime.Serialization.Formatters.Binary

Types 

  • Binary Serialization
  • XML Serialization
  • JSON Serialization 
-----------------------------------------------------------------------------------------------------------------------------

Extension method in c# example

 

Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are static methods, to define an extension method, first of all, define a static class.


(or)

Extension methods, as the name suggests, are additional methods. Extension methods allow you to inject additional methods without modifying, deriving or recompiling the original class, struct, or interface. Extension methods can be added to your own custom class, .NET framework classes, or third-party classes or interfaces.
C# extension method is a static method of a static class, where the "this" modifier is applied to the first parameter. The type of the first parameter will be the type that is extended.

Extension methods are only in scope when you explicitly import the namespace into your source code a using directive.

int i = 10;

bool result = i.is greater than(100); //returns false

 Note:

·         Extension methods are always defined as static methods, but when they are bound with any class or structure they will convert into non-static methods. The extension method does not support method overriding

·         You can also add new methods in the sealed class also using an extension method concept.

·         It cannot apply to fields, properties, or events.

·         The only difference between a regular static method and an extension method is that the first parameter of the extension method specifies the type that it is going to the operator on, preceded by this keyword. Extension methods can be used anywhere in the application by including the namespace of the extension method.

 

 Advantages:

 

·         The main advantage of the extension method is to add new methods in the existing class without using inheritance.

·         You can add new methods in the existing class without modifying the source code of the existing class.

·         It can also work with the sealed classes.

 ----------------------------------------------------------------------------------------------------------------------------

 Q)SOLID Design Principles in C#?

SOLID design principles in C# are basic design principles. SOLID stands for Single Responsibility Principle (SRP), Open closed Principle (OSP), Liskov substitution Principle (LSP), Interface Segregation Principle (ISP), and Dependency Inversion Principle (DIP). 

SOLID Principles

There are five SOLID principles:

Single Responsibility Principle (SRP)

Open-Closed Principle (OCP)

Liskov Substitution Principle (LSP)

Interface Segregation Principle (ISP)

Dependency Inversion Principle (DIP)

Single Responsibility Principle (SRP)

A class should have only one reason to change.
(Or)
Each software module or class should have only one reason to change“. In other words, we can say that each module or class should have only one responsibility to do.

So we need to design the software in such a way that everything in a class or module should be related to a single responsibility. That does not mean your class should contain only one method or property, you can have multiple members (methods or properties) as long as they are related to a single responsibility or functionality. So, with the help of SRP in C#, the classes become smaller and cleaner and thus easier to maintain.

Let us understand the need for the Single Responsibility Principle in C# with an example. Suppose we need to design an Invoice class. As we know an Invoice class is basically used to calculate various amounts based on its data. The Invoice class does not know how to retrieve the data, or how to format the data for display, print, logging, or sending an email, etc. 

If we write the database logic, business logic as well as display logic in a single class, then our class performing multiple responsibilities. Then it becomes very difficult to change one responsibility without breaking the other responsibilities. So, by mixing multiple responsibilities into a single class, we are getting the following disadvantage,

  1. Difficult to understand
  2. Difficult to test
  3. Chance of duplicating the logic of other parts of the application





Open-Closed Principle:

The Open-Closed Principle states thatsoftware entities such as modules, classes, functions, etc. should be open for extension, but closed for modification“.

Let us understand the above definition in simple words. Here we need to understand two things. The first thing is Open for extension and the second thing is Closed for modification. The Open for extension means we need to design the software modules/classes in such a way that the new responsibilities or functionalities should be added easily when new requirements come. On the other hand, Closed for modification means, we should not modify the class/module until we find some bugs.

The reason for this is, we have already developed a class/module and it has gone through the unit testing phase. So we should not have to change this as it affects the existing functionalities. In simple words, we can say that we should develop one module/class in such a way that it should allow its behavior to be extended without altering its source code.

Implementation Guidelines for the Open-Closed Principle (OCP) in C#
  1. The easiest way to implement the Open-Closed Principle in C# is to add the new functionalities by creating new derived classes which should be inherited from the original base class.
  2. Another way is to allow the client to access the original class with an abstract interface.
  3. So, at any given point of time when there is a change in requirement or any new requirement comes then instead of touching the existing functionality, it’s always better and suggested to create new derived classes and leave the original class implementation as it is.

Ex: Without using Open-Closed Principles in c#

namespace SOLID_PRINCIPLES.OCP

{

    public class Invoice

    {       

        public double GetInvoiceDiscount(double amount, InvoiceType invoiceType)

        {

            double finalAmount = 0;

            if (invoiceType == InvoiceType.FinalInvoice)

            {

                finalAmount = amount - 100;

            }

            else if (invoiceType == InvoiceType.ProposedInvoice)

            {

                finalAmount = amount - 50;

            }

            return finalAmount;

        }

    }

    public enum InvoiceType

    {

        FinalInvoice,

        ProposedInvoice

    };

}

Example: With Open-Closed Principle in C#

namespace SOLID_PRINCIPLES.OCP

{

    public class Invoice

    {

        public virtual double GetInvoiceDiscount(double amount)

        {

            return amount - 10;

        }

    }

    public class FinalInvoice : Invoice

    {

        public override double GetInvoiceDiscount(double amount)

        {

            return base.GetInvoiceDiscount(amount) - 50;

        }

    }

    public class ProposedInvoice : Invoice

    {

        public override double GetInvoiceDiscount(double amount)

        {

            return base.GetInvoiceDiscount(amount) - 40;

        }

    }

    public class RecurringInvoice : Invoice

    {

        public override double GetInvoiceDiscount(double amount)

        {

            return base.GetInvoiceDiscount(amount) - 30;

        }

    }

}

Modify the Main method of the Program class as shown below to test the application.

using System;

namespace SOLID_PRINCIPLES.OCP

{

    class Program

    {

        static void Main(string[] args)

        {

            Invoice FInvoice = new FinalInvoice();

            Invoice PInvoice = new ProposedInvoice();

            Invoice RInvoice = new RecurringInvoice();

            double FInvoiceAmount = FInvoice.GetInvoiceDiscount(10000);

            double PInvoiceAmount = PInvoice.GetInvoiceDiscount(10000);

            double RInvoiceAmount = RInvoice.GetInvoiceDiscount(10000);

            Console.ReadKey();

        }

    }

}

Now, the Invoice class is closed for modification. But it is open for the extension as it allows creating new classes deriving from the Invoice class which clearly follows the Open-Closed Principle in C#. 



The Liskov Substitution Principle (LSP) states that "you should be able to use any derived class instead of a parent class and have it behave in the same manner without modification". It ensures that a derived class does not affect the behavior of the parent class, in other words,, that a derived class must be substitutable for its base class.

 This principle is just an extension of the Open-Closed Principle and it means that we must ensure that new derived classes extend the base classes without changing their behavior. I will explain this with a real-world example that violates LSP.

 A father is a doctor whereas his son wants to become a cricketer. So here the son can't replace his father even though they both belong to the same family hierarchy.

 

Example: Without using the Liskov Substitution Principle in C#:

namespace SOLID_PRINCIPLES.LSP

{

    class Program

    {

        static void Main(string[] args)

        {

            Apple apple = new Orange();

            Console.WriteLine(apple.GetColor());

        }

    }

    public class Apple

    {

        public virtual string GetColor()

        {

            return "Red";

        }

    }

    public class Orange : Apple

    {

        public override string GetColor()

        {

            return "Orange";

        }

    }

}

Let’s modify the previous example to follow the Liskov Substitution Principle. Here, first, we need a generic base class such as Fruit which is going to be the base class for both Apple and Orange. Now you can replace the Fruit class object with its subtypes either Apple and Orage and it will behave correctly. Now, you can see in the below code, we created the super Fruit class as an abstract class with the GetColor abstract method and then the Apple and Orange class inherited from the Fruit class and implement the GetColor method. 

Example Using the Liskov Substitution Principle in C#

namespace SOLID_PRINCIPLES.LSP

{

    class Program

    {

        static void Main(string[] args)

        {

            Fruit fruit = new Orange();

            Console.WriteLine(fruit.GetColor());

            fruit = new Apple();

            Console.WriteLine(fruit.GetColor());

        }

    }

    public abstract class Fruit

    {

        public abstract string GetColor();

    }

    public class Apple: Fruit

    {

        public override string GetColor()

        {

            return "Red";

        }

    }

    public class Orange : Fruit

    {

        public override string GetColor()

        {

            return "Orange";

        }

    }

}

Liskov Substitution Principle (LSP):

The Liskov Substitution Principle (LSP) states that "you should be able to use any derived class instead of a parent class and have it behave in the same manner without modification". It ensures that a derived class does not affect the behavior of the parent class, in other words,, that a derived class must be substitutable for its base class.

This principle is just an extension of the Open-Closed Principle and it means that we must ensure that new derived classes extend the base classes without changing their behavior. I will explain this with a real-world example that violates LSP.

 A father is a doctor whereas his son wants to become a cricketer. So here the son can't replace his father even though they both belong to the same family hierarchy.

 

Example: Without using the Liskov Substitution Principle in C#:

namespace SOLID_PRINCIPLES.LSP

{

    class Program

    {

        static void Main(string[] args)

        {

            Apple apple = new Orange();

            Console.WriteLine(apple.GetColor());

        }

    }
public class Apple

    {

        public virtual string GetColor()

        {

            return "Red";

        }

    }

    public class Orange: Apple

    {

        public override string GetColor()

        {

            return "Orange";

        }

    }

}

Example Using the Liskov Substitution Principle in C#

Let’s modify the previous example to follow the Liskov Substitution Principle. Here, first, we need a generic base class such as Fruit which is going to be the base class for both Apple and Orange. Now you can replace the Fruit class object with its subtypes either Apple and Orage and it will behave correctly. Now, you can see in the below code, we created the super Fruit class as an abstract class with the GetColor abstract method and then the Apple and Orange class inherited from the Fruit class and implement the GetColor method. 

namespace SOLID_PRINCIPLES.LSP

{

    class Program

    {

        static void Main(string[] args)

        {

            Fruit fruit = new Orange();

            Console.WriteLine(fruit.GetColor());

            fruit = new Apple();

            Console.WriteLine(fruit.GetColor());

        }

    }

    public abstract class Fruit

    {

        public abstract string GetColor();

    }

    public class Apple : Fruit

    {

        public override string GetColor()

        {

            return "Red";

        }

    }

    public class Orange: Fruit

    {

        public override string GetColor()

        {

            return "Orange";

        }

    }

}




Interface Segregation Principle (ISP):

No client should be forced to implement methods that it does not use, and the contracts should be broken down into thin ones.

Clients should not be forced to implement any methods they don’t use. Rather than one fat interface, numerous little interfaces are preferred based on groups of methods with each interface serving one submodule“.

Let us break down the above definition into two parts.

  1. First, no class should be forced to implement any method(s) of an interface they don’t use.
  2. Secondly, instead of creating large or you can say fat interfaces, create multiple smaller interfaces with the aim that the clients should only think about the methods that are of interest to them.

As per the  Single responsibility principle of SOLID, like classes, interfaces also should have a single responsibility. That means we shouldn’t force any class to implement any method(s) which they don’t require.

namespace SOLID_PRINCIPLES.ISP

{

    public interface IPrinterTasks

    {

        void Print(string PrintContent);

        void Scan(string ScanContent);

    }

    interface IFaxTasks

    {

        void Fax(string content);

    }

    interface IPrintDuplexTasks

    {

        void PrintDuplex(string content);

    }

}

namespace SOLID_PRINCIPLES.ISP

{

    public class HPLaserJetPrinter : IPrinterTasks, IFaxTasks,

                                     IPrintDuplexTasks

    {

        public void Print(string PrintContent)

        {

            Console.WriteLine("Print Done");

        }

        public void Scan(string ScanContent)

        {

            Console.WriteLine("Scan content");

        }

        public void Fax(string FaxContent)

        {

            Console.WriteLine("Fax content");

        }

        public void PrintDuplex(string PrintDuplexContent)

        {

            Console.WriteLine("Print Duplex content");

        }

    }

}

namespace SOLID_PRINCIPLES.ISP

{

    class LiquidInkjetPrinter : IPrinterTasks

    {

        public void Print(string PrintContent)

        {

            Console.WriteLine("Print Done");

        }

        public void Scan(string ScanContent)

        {

            Console.WriteLine("Scan content");

        }

    }

}



Dependency Inversion Principle (DIP):

High-level modules should not depend on low-level modules. Both should depend on abstractions.

Abstractions should not depend on details. Details should depend on abstractions.

The principle says that high-level modules should depend on abstraction, not on the details, of low-

level modules. In simple words, the principle says that there should not be a tight coupling among

components of software and to avoid that, the components should depend on abstraction.

The terms Dependency Injection (DI) and Inversion of Control (IoC) are generally used interchangeably to express the same design pattern. The pattern was initially called IoC, but Martin

Fowler (known for designing the enterprise software) anticipated the name as DI because all frameworks or runtime invert the control in some way and he wanted to know which aspect of control was being inverted.

Inversion of Control (IoC) is a technique to implement the Dependency Inversion Principle in C#.

Inversion of control can be implemented using either an abstract class or interface. The rule is that

the lower-level entities should join the contract to a single interface and the higher-level entities

will use only entities that are implementing the interface. This technique removes the dependency

between the entities.

The most important point that you need to remember while developing real-time applications, always to try to keep the High-level module and Low-level module as loosely coupled as possible.

When a class knows about the design and implementation of another class, it raises the risk that if we

do any changes to one class will break the other class. So we must keep these high-level and low-level

modules/classes loosely coupled as much as possible. To do that, we need to make both of them dependent on abstractions instead of knowing each other.

namespace SOLID_PRINCIPLES.DIP

{

    public interface IEmployeeDataAccess

    {

        Employee GetEmployeeDetails(int id);

    }

}

namespace SOLID_PRINCIPLES.DIP

{

    public class EmployeeDataAccess: IEmployeeDataAccess

    {

        public Employee GetEmployeeDetails(int id)

        {

            // In real time get the employee details from DB

            //but here we are hardcoded the employee details

            Employee emp = new Employee()

            {

                ID = id,

                Name = "Pranaya",

                Department = "IT",

                Salary = 10000

            };

            return emp;

        }

    }

}

namespace SOLID_PRINCIPLES.DIP

{

    public class DataAccessFactory

    {

        public static IEmployeeDataAccess GetEmployeeDataAccessObj()

        {

            return new EmployeeDataAccess();

        }

    }

}

namespace SOLID_PRINCIPLES.DIP

{

    public class EmployeeBusinessLogic

    {

        IEmployeeDataAccess _EmployeeDataAccess;

        public EmployeeBusinessLogic()

        {

            _EmployeeDataAccess = DataAccessFactory.GetEmployeeDataAccessObj();

        }

        public Employee GetEmployeeDetails(int id)

        {

            return _EmployeeDataAccess.GetEmployeeDetails(id);

        }

    }

}

Advantages of implementing the Dependency Inversion Principle in C#:

Now, the EmployeeBusinessLogic and EmployeeDataAccess classes are loosely coupled classes because EmployeeBusinessLogic does not depend on concrete EmployeeDataAccess classes, instead, it includes a reference of the IEmployeeDataAccess interface. So now, we can easily use another class that implements IEmployeeDataAccess with a different implementation.
----------------------------------
-------------------------------------------------------------------------------------------

Design Patterns in C#?

There are three basic classifications of patterns Creational, Structural, and Behavioral patterns.

Creational Patterns(object creation and initialization)

The Creational Design Pattern deals with Object Creation and Initialization. The Creational Design Pattern gives the programmer more flexibility in deciding which objects need to be created for a given case. For example, if we have a huge project, a huge project means we have a lot of classes, a lot of classes mean we are dealing with a lot of objects. So we need to create different objects (like new Customer(), new product(), new invoice(), etc.) based on some conditions. If the object creations logic based on some condition is implemented in the client code, then it leads to lots of complicated logic in the client code. That means if the object creations and initialization logic are not centralized then it leads to a very complicated code. The Creational Design Pattern helps us to centralized the object creation logic and depending upon the condition, it will create and initialize the appropriate object and returns that object.

Abstract Factory: Creates an instance of several families of classes

Builder: Separates object construction from its representation

Factory Method: Creates an instance of several derived classes

Prototype: A fully initialized instance to be copied or cloned

Singleton: A class in which only a single instance can exist

Note

The best way to remember the Creational pattern is by remembering ABFPS (Abraham Became the First President of the States).

Structural Patterns(Structural Changes of class and interfaces, and the relationship between classes)

The Structural Design Pattern is basically used to manage the structure of classes and interface as well as manage the relationship between the classes. For example, if we have a Customer and Product class and the Product class is used inside the Customer class making one to many relationships. Tomorrow, as the project proceeds, now we want to keep away the product class from the Customer class as we want to use the Product and Customer class independently. This is a structural change and we don’t want this structural change to affect our project. This is where the Structural Design Pattern helps us.

Adapter: Match interfaces of different classes.

Bridge: Separates an object's abstraction from its implementation.

Composite: A tree structure of simple and composite objects.

Decorator: Add responsibilities to objects dynamically.

Flyweight: A fine-grained instance used for efficient sharing.

Proxy: An object representing another object.

Note

To remember structural pattern best is (ABCDFFP)

Behavioral Patterns(Communication Between Objects)

The Behavioral Design Patterns deal with the communication between Classes and objects. That means if you want to change the behavior of a class and again you want it to affect other classes of the project as well. For example, you have an Invoice class that currently applying taxes as 18%. Tomorrow if you have to add another extra tax. That means you are changing the behavior of a class. To solve such types of Behavioral issues Behavioral Design Pattern comes into the picture.

Mediator: Defines simplified communication between classes.

Memento: Capture and restore an object's internal state.

Interpreter: A way to include language elements in a program.

Iterator: Sequentially access the elements of a collection.

Chain of Resp: A way of passing a request between a chain of objects.

Command: Encapsulate a command request as an object.

State: Alter an object's behavior when its state changes.

Strategy: Encapsulates an algorithm inside a class.

Observer: A way of notifying change to a number of classes.

Template Method: Defer the exact steps of an algorithm to a subclass.

Visitor: Defines a new operation to a class without change.

Note: Just remember Music....... 2 MICS On TV (MMIICCSSOTV).

-----------------------------------------------------------------------------------------------------------------------------

Why do we need the Dependency Injection Design Pattern in C#?

The Dependency Injection Design Pattern in C# allows us to develop loosely coupled software components.  In other words, we can say that Dependency Injection Design Pattern is used to reduce the tight coupling between the software components. As a result, we can easily manage future changes and other complexity in our application. Before understanding the Dependency Injection Design Pattern using C#, let us first understand what tight coupling is and what loose coupling in software development is. So let’s understand these two concepts first.

What is Tight Coupling in Software Design?

Tight coupling means two objects are dependent on each other. That means when a class is dependent on another class, then it is said to be a tight coupling between these two classes. In that case, if we

change the dependent object, then we also need to change the classes where this dependent object is

used. If your application is a small one, then it is not that difficult to handle but if you have a big

enterprise-level application, then it’s really very difficult to handle to make these changes.

What is Loose Coupling in Software Design?

Loosely coupling means two objects are independent of each other. That means if we change one object then it will not affect another object. The loosely coupled nature of software development allows us to manage future changes easily and also allows us to manage the complexity of the application.

What is Dependency Injection Design Pattern in C#?

The Dependency Injection Design Pattern in C# is a process in which we are injecting the object of a class into a class that depends on that object. The Dependency Injection design pattern is the most commonly used design pattern nowadays to remove the dependencies between the objects.

Dependency Injection (DI) is a design pattern used to implement IoC (Inversion of Control). It allows the creation of dependency objects outside of a class and provides those objects to a class in different ways. Using Dependency Injection Design Pattern, we move the creation and binding of the dependent objects outside of the class that depends on them.

Dependency Injection pattern involves 3 types of classes:

Client Class: The Client class (dependent class) is a class that depends on the service class.

Service Class: The Service class (dependency) is a class that provides service to the client class.

Injector Class: The Injector class injects the service class object into the client class.

Different Types of Dependency Injection in C#?

The injector class injects the dependency object into a class in three different ways. They are as

follows.

Constructor Injection: When the Injector injects the dependency object (i.e. service) through the

client class constructor, then it is called Constructor Dependecy Injection.

The Injection happens in the constructor, bypassing the Service that implements the IService Interface. The dependencies are assembled by a "Builder" and Builder responsibilities are as follows:Knowing the types of each IService
According to the request, feed the abstract IService to the Client.

Advantages of Constructor Dependency Injection

The Constructor Dependency Injection Design Pattern makes a strong dependency contract This design pattern support testing as the dependencies are passed through the constructor.

Property Injection: When the Injector injects the dependency object (i.e. service) through the public

property of the client class, then it is called Property Dependency Injection. This is also called the Settler injection. In Property Dependency Injection, we need to supply the dependency object through a public property of the client class

Method Injection: When the Injector injects the dependency object (i.e. service) through a public method of the client class, then it is called Method Dependency Injection. It could be useful, where the whole class does not need the dependency, only one method having that dependency.

Constructor Injection

public interface IService {

 void Serve();

}

public class Service1 : IService {

 public void Serve() { Console.WriteLine("Service1 Called"); }

}

public class Service2 : IService {

 public void Serve() { Console.WriteLine("Service2 Called"); }

}

public class Client {

 private IService _service;

 public Client(IService service) {

 this._service = service;

 }

 public ServeMethod() { this._service.Serve(); }

}

 

class Program

{

 static void Main(string[] args)

 {

 //creating object

 Service1 s1 = new Service1();

 //passing dependency

 Client c1 = new Client(s1);

 //TO DO:

 Service2 s2 = new Service2();

 //passing dependency

 c1 = new Client(s2);

 //TO DO:

 }

}

Ex: Property/Setter Injection

public interface IService {

 void Serve();

}

public class Service1 : IService {

 public void Serve() { Console.WriteLine("Service1 Called"); }

}

public class Service2 : IService {

 public void Serve() { Console.WriteLine("Service2 Called"); }

}

public class Client {

 private IService _service;

 public IService Service {

 set { this._service = value; }

 }

 public ServeMethod() { this._service.Serve(); }

}

class Program

{

 static void Main(string[] args)

 {

 //creating object

 Service1 s1 = new Service1();

 Client client = new Client();

 client.Service = s1; //passing dependency

 //TO DO:

 Service2 s2 = new Service2();

 client.Service = s2; //passing dependency

 //TO DO:

 }

}

Ex:Method Injection

public interface IService {

 void Serve();

}

public class Service1 : IService {

 public void Serve() { Console.WriteLine("Service1 Called"); }

}

public class Service2 : IService {

 public void Serve() { Console.WriteLine("Service2 Called"); }

}

public class Client {

 private IService _service;

 public void Start(IService service) {

 service.Serve();

 }

}

class Program

{

 static void Main(string[] args)

 {

 //creating object

 Service1 s1 = new Service1();

 Client client = new Client();

 client.Start(s1); //passing dependency

 //TO DO:

 Service2 s2 = new Service2();

 client.Start(s2); //passing dependency

 }

}

Advantages of Dependency Injection

Reduces class coupling

Increases code reusability

Improves code maintainability

Make unit testing possible
----------------------------
-------------------------------------------------------------------------------------------------

Singleton Pattern versus Static Class

In simple words, Singleton is a pattern and not a keyword. The Singleton pattern has several advantages over static classes. A singleton allows a class for which there is just one, persistent instance across the lifetime of an application. That means, it created a single instance and that instance (a reference to that instance) can be passed as a parameter to other methods and treated as a normal object. While a static class allows only static methods and you cannot pass the static class as a parameter. A Singleton can implement interfaces, inherit from other classes and allow inheritance. While a static class cannot inherit its instance members. So Singleton is more flexible than static classes and can maintain state.

A Singleton can be initialized lazily or asynchronously and loaded automatically by the .NET Framework CLR (common language runtime) when the program or namespace containing the class is loaded. While a static class is generally initialized when it is first loaded and it will lead to potential classloader issues.

Singleton class follows the Object-Oriented Principles so that singletons can be handled polymorphically without forcing their users to assume that there is only one instance. While static cannot.

Other differences:

  • Singleton Objects are stored on the heap while static class is stored in the stack.
  • Singleton Objects can have a constructor while Static Class cannot.
  • Singleton Objects can dispose but not a static class.
  • Singleton Objects can clone but not with a static class.

In short, single means a single object across the application life cycle, so the scope is at the application level. The static does not have any Object pointer, so the scope is at the App Domain level. Moreover, both should be implemented to be thread-safe.

Static

Singleton

We don’t need to instantiate a static class and can access properties and methods with the class names.

Instance creation is necessary to access methods and properties. We create instances using static property defined for this purpose.

Static class cannot be passed a parameter in another class

We can pass instances of a singleton as a parameter to another class method.

A static keyword is required in all the methods defined in the Static class.

The Singleton class does not require you to use the static keyword everywhere.

Static class does not support interface inheritance. It throws the error “static classes cannot implement interfaces”

Singleton class can implement the interface

The static variable does not reset until the server is restarted.

 

It cannot have instance members. We need to call all the static methods explicitly.

This may have instance members.

Code example

//Static Class

public static class Stat{

static Stat(){

 Console.WriteLine("static constr");

 }

 public static void Get(){

 Console.WriteLine("stat method called");

 }

}

//Singleton pattern

public class SingleTon{

 private static SingleTon obj = null;

 private static readonly Object locker = new Object();

 private SingleTon(){

 }

 public int UserId {get;set;}

 public static SingleTon GetInstance {

 get{

 if(obj == null){

 lock(locker){

 if(obj == null){

 obj = new SingleTon();

 }

 }

 }

 return obj;

 }

 }

}

-----------------------------------------------------------------------------------------------------------------------------

Code-first vs Model/Database-first
There are 3 approaches through which the Entity framework is implemented. 

Database First

Code First

Model First

Of these Database first and Code First is the most used ones.

Code First Approach

In the code first approach, we will first create entity classes with properties defined in them. The entity

framework will create the database and tables based on the entity classes defined. So the database is

generated from the code. When the dot net code is run database will get created.

Advantages

You can create the database and tables from your business objects.

You can specify which related collections are to be eagerly loaded, or not be serialized at all.

Database version control.

Good for small applications.

Disadvantages

You have to write everything related to the database in the visual studio code.

For stored procedures, you have to map stored procedures using Fluent API and write Stored Procedure

inside the code.

If you want to change anything in the database tables you to make changes in the entity classes in the

code file and run the update database from the package manager console.

Not preferred for Data-intensive applications. 

Database First Approach

In this approach databases and tables are created first. Then you create an Entity Data Model using the

created database.

Advantages

Simple to create the data model

 Graphical user interface.

  Mapping and creating keys and relationships are easy as you need not have to write any code.

 Preferred for data-intense and large applications

Disadvantages

Using an existing database to generate a .edmx model file and the associated code models results in a

a giant pile of auto-generated code.

When you need to add any functionality to the generated model you have to extend the model class generated.

Which Approach To Use?

If you are starting a new project, with a new database, use EF Core Code First

If you are starting a new project, but there is an existing database you want to talk to, use EF Core

Database First.

-----------------------------------------------------------------------------------------------------------------------------

C# - Tuple

The Tuple<T> class was introduced in .NET Framework 4.0. A tuple is a data structure that contains a sequence of elements of different data types. It can be used where you want to have a data structure to hold an object with properties, but you don't want to create a separate type for it.

Tuple<T1, T2, T3, T4, T5, T6, T7, TRest>

Tuple<int, string, string> person =

                        new Tuple <int, string, string>(1, "Steve", "Jobs")

var person = Tuple.Create(1, "Steve", "Jobs");

var numbers = Tuple.Create(1, 2, 3, 4, 5, 6, 7, 8);

var person = Tuple.Create(1, "Steve", "Jobs");

person.Item1; // returns 1

person.Item2; // returns "Steve"

person.Item3; // returns "Jobs"

var numbers = Tuple.Create("One", 2, 3, "Four", 5, "Six", 7, 8);

numbers.Item1; // returns "One"

numbers.Item2; // returns 2

numbers.Item3; // returns 3

numbers.Item4; // returns "Four"

numbers.Item5; // returns 5

numbers.Item6; // returns "Six"

numbers.Item7; // returns 7

numbers.Rest; // returns (8)

numbers.Rest.Item1; // returns 8

Nested Tuples

If you want to include more than eight elements in a tuple, you can do that by nesting another tuple object as the eighth element. The last nested tuple can be accessed using the Rest property. To access the nested tuple's element, use the Rest.Item1.Item<elelementNumber> property.

var numbers = Tuple.Create(1, 2, 3, 4, 5, 6, 7, Tuple.Create(8, 9, 10, 11, 12, 13));

numbers.Item1; // returns 1

numbers.Item7; // returns 7

numbers.Rest.Item1; //returns (8, 9, 10, 11, 12, 13)

numbers.Rest.Item1.Item1; //returns 8

numbers.Rest.Item1.Item2; //returns 9

var numbers = Tuple.Create(1, 2, Tuple.Create(3, 4, 5, 6, 7,  8), 9, 10, 11, 12, 13 );

numbers.Item1; // returns 1

numbers.Item2; // returns 2

numbers.Item3; // returns (3, 4, 5, 6, 7,  8)

numbers.Item3.Item1; // returns 3

numbers.Item4; // returns 9

numbers.Rest.Item1; //returns 13

Tuple as a Method Parameter

A method can have a tuple as a parameter.

static void Main(string[] args)

{

    var person = Tuple.Create(1, "Steve", "Jobs");

    DisplayTuple(person);

}

static void DisplayTuple(Tuple<int,string,string> person)

{

    Console.WriteLine($"Id = { person.Item1}");

    Console.WriteLine($"First Name = { person.Item2}");

    Console.WriteLine($"Last Name = { person.Item3}");

}

Tuple as a Return Type

A Tuple can be returned from a method.

static void Main(string[] args)

{

    var person = GetPerson();

}

static Tuple<int, string, string> GetPerson()

{

    return Tuple.Create(1, "Bill", "Gates");

}

Usage of Tuple

Tuples can be used in the following scenarios:

 

When you want to return multiple values from a method without using ref or out parameters.

When you want to pass multiple values to a method through a single parameter.

When you want to hold a database record or some values temporarily without creating a separate class.

Tuple Limitations:

The Tuple is a reference type and not a value type. It allocates on the heap and could result in CPU-intensive operations.

The Tuple is limited to include eight elements. You need to use nested tuples if you need to store more elements. However, this may result in ambiguity.

The Tuple elements can be accessed using properties with a name pattern Item<elementNumber>, which does not make sense.
-----------------------------------------------------------------------------------------------------------------------------

MULTI-THREADING IN C#

Threads are lightweight processes that act as a path through which a process can be executed. Every process/application runs by default with a single thread. The entire code of the application gets executed sequentially in a single thread.

Multithreaded applications introduced the capability to process the independent code concurrently in more than one thread. Multithreading helps to reduce the time of execution, and also makes use of the CPU power at an optimum level.

System.threading namespace contains the classes and interface which enables multithreading in an application.

LIFE CYCLE OF THREAD

Here’s the life cycle of a thread -

Unstarted State - State at which the instance of the thread is created but hasn’t yet started to run. In other words, the Start() method of the Thread is not being called.

Eg - var thread = new Thread();

Ready State - A thread that is ready to run is in a runnable/ready state. This means an instance of the thread is created and it is ready to run at any moment.

Running State - As the name implies, the thread that is running is termed to be in a running state.

Non-Runnable State - State at which the thread is not executable. Below are few states which are considered non-runnable when,

​ Sleep() method of the thread is active

​ Wait() method of the thread is active

​ Suspend() method of the thread is called

​ Waiting for I/O Operations

Dead State - When the thread completes the task assigned to it, it is considered to be in a dead state.

FREQUENTLY ACCESSED MEMBER/PROPERTY OF A THREAD

Methods that are frequently accessed

public void Start() - This method is invoked to start a thread.

public static void Sleep(int milliseconds timeout) - This method is used to sleep the current thread for the defined millisecond period. As the method is static, it is invoked with the class name directly (Thread. Sleep(2000)).

public void Suspend() - Suspends the thread. It does not affect if invoked when the thread is already suspended. Also, it throws an exception when invoked before starting or after the thread is dead.

public void Resume() - Resumes the suspended thread. It throws an exception when invoked and the thread has not started or when it is not suspended.

public void Abort() - Terminated the calling thread.

Properties that are frequently accessed.

public string Name { get; set; } - Provides the name of the thread object. Also, users can assign thread names at run time.

public bool IsAlive { get; } - Provides whether the thread object is alive. It returns true or false. It is a read-only property.

public ThreadState ThreadState { get; } - Provides the state of the thread. It returns the state with ThreadState as the return type.

public ThreadPriority Priority { get; set; } - Users can assign as well as read the priority of the thread instance using this property. Priority can be set with the type ThreadPriority(enum). 

-----------------------------------------------------------------------------------------------------------------------------

Q) What is the difference between Process and Thread?

A process is started when you start an Application. A process is a collection of resources like virtual address space, code, security contexts, etc. A process can start multiple threads. Every process is start with a single thread called the primary thread. You can create n number of threads in a process. Threads share the resources allocated to the process.

A process is the parent and threads are his children.

-----------------------------------------------------------------------------------------------------------------------------

Q)How to start a Thread in C#?

We have to use the Thread class provided by System. Threading namespace. In the constructor of the class, we have to pass the method name which we want to run in a separate thread. After that we have to call the start method of the Thread class.

using System;

using System. Threading;

namespace ConsoleApplication1

{

    class Program

    {

        static void Main(string[] args)

        {

            Thread th = new Thread(ThreadMethod);

            th.Start();

        }

        private static void ThreadMethod()

        {

            Console.WriteLine("Another Thread");

        }

    }

-----------------------------------------------------------------------------------------------------------------------------

Q)How to pass parameter in Thread?

In the constructor of Thread, we can pass the method name which accepts only a single parameter. Then we have to pass the parameter into the Start method. Below is the example.

static void Main(string[] args)

{

    Thread th = new Thread(ThreadMethod);

    th.Start("Hello");

} 

private static void ThreadMethod(object args)

{

    Console.WriteLine(args.ToString());

}
-----------------------------------------------------------------------------------------------------------------------------

Q)What is a volatile keyword?

Volatile is used for serializing the access of variables without using the synchronization primitives. You can use volatile with the below types:

References types

Pointer types

Values types

IntPtr

1

public volatile int number;
-----------------------------------------------------------------------------------------------------------------------------

Q)How can you share data between multiple threads?

There are two ways to share data between multiple threads:

Concurrent collection classes

Using Synchronization Primitives
-----------------------------------------------------------------------------------------------------------------------------

Q) What are Concurrent Collection Classes?

.NET Framework class library comes with Concurrent collection classes so that multiple threads can share collection data between them without using synchronization primitives.

There are four types of Concurrent classes.

ConcurrentQueue

ConcurrentStack

ConcurrentDictionary

ConcurrentBag
-----------------------------------------------------------------------------------------------------------------------------

Q)What is synchronization and why it is important?

We use multiple threads to improve the performance of our application. When multiple threads shares data between there is a chance of data corruption. When one thread is writing to the variable another thread is reading the same variable at the same time there is a chance of reading corrupt data.
-----------------------------------------------------------------------------------------------------------------------------

Q)Can you count some names of Synchronization primitives?

Monitor

Mutex

SpinLock

ReaderWriterLock

Semaphore

AutoResetEvent

ManualResetEvent

InterLocked

CountDownEvent

Barrier
-----------------------------------------------------------------------------------------------------------------------------

 Q) What is Deadlock?

A deadlock is a situation in which two or more processes cannot complete their work. They are blocked and each thread waiting for other threads to release the resources they want.

 For example, you have two threads T1 and T2 and you have two resources R1 and R2. Both threads want to work with both resources. But in the opposite fashion, T1 wants to work with R1 first and then with R2. T2 wants to work with R2 first and then with R1.

Both threads start at the same time. T1 locked R1 while at the same time T2 locked R2. Now T1 wants a lock on R2 which is already locked by T2 and T2 wants a lock on R1 which is already locked by T1. Both threads waiting for other threads to unlock the resources. Both threads are waiting for infinite time and can't continue forever.

 Types of  necessary conditions for Deadlock

 Mutual Exclusion: Resources involved must be unshareable between multiple threads.

Hold and Wait: Threads hold the resources they have allocated and waiting for the resources they want.

No pre-emption: If the thread locks the resource, other threads cannot take the resource until the thread releases it.

Circular Wait: A circular chain must exist in which each thread waiting for other threads to release resources.
-----------------------------------------------------------------------------------------------------------------------------

Q)What is LiveLock?

A livelock is very similar to deadlock except for involved threads states are continually changing their state but still, they cannot complete their work.

 A real-world example of livelock occurs when two people meet in a narrow corridor, and each tries to be polite by moving aside to let the other pass, but they end up swaying from side to side without making any progress because they both repeatedly move the same way at the same time.

 Suppose one thread has odd numbers like 1,3,5 and the other thread has even numbers 2,4,6. How can you synchronize between them and print the numbers in order?

We have to take two AutoResetEvents which each signal each other after they print one number. Below is the full code.

using System;

using System. Threading;

using System.Threading.Tasks;

namespace ConsoleApplication1

{

    class Program

    {

        static AutoResetEvent auto1 = new AutoResetEvent(false);

        static AutoResetEvent auto2 = new AutoResetEvent(false);

        static void Main(string[] args)

        {

            var t1 = Task.Factory.StartNew(() => PrintOddNumbers());

            var t2 = Task.Factory.StartNew(() => PrintEvenNumbers());

            Task.WaitAny(t1, t2);

            Console.WriteLine("End");

            Console.ReadLine();

        }

        static void PrintOddNumbers()

        {

            int[] arr = new int[] { 1, 3, 5, 7, 9, 11, 13, 15 };

            foreach (var item in arr)

            {

                Console.WriteLine(item);

                auto2.Set();

                auto1.WaitOne();

            }

        }

        static void PrintEvenNumbers()

        {

            int[] arr = new int[] { 2, 4, 6, 8, 10, 12, 14 };

            foreach (var item in arr)

            {

                auto2.WaitOne();

                Console.WriteLine(item);

                auto1.Set();

            }

            auto1.Set();

        }

    }

}

-----------------------------------------------------------------------------------------------------------------------------

Q) What is an immutable object?

An immutable object is an object which states cannot be changed after creation. Immutable objects are useful in concurrent programming as they are thread-safe.

"String" objects are examples of immutable objects because we can not change the value of a string after it is created. Below is the code in which we try to change the second index char of string which gives us an error.

string str = "Hello";

str[0] = 'm'; //Doesn't work; Property or indexer 'string.this[int]' cannot be assigned to --it is read-only

Why are the keywords necessary for supporting immutable objects?

There are two keywords provided by CLR.

const

read-only

static void Main(string[] args)

{

            Person p1 = new Person(1, "Name 1");

 }

public class Person

{

    private readonly int id;

        private readonly string name;

        public Person(int id, string name)

        {

            this.id = id;

            this.name = name;

    }

}
-----------------------------------------------------------------------------------------------------------------------------

Q) What is AutoResetEvent?

AutoResetEvent is a synchronization mechanism that works on a bool variable. If the bool variable is false then the thread is blocked. If the bool variable is true then the thread is unblocked.

AutoResetEvent contains two main methods:

WaitOne() : Blocks the current thread

Set() : Unblock the current thread

Reset() : Sets the state of the event to non-signaled.

using System;

using System. Threading;

using System.Threading.Tasks;

namespace ConsoleApplication1

{

    class Program

    {

        static AutoResetEvent autoEvent = new AutoResetEvent(false);

        static void Main(string[] args)

        {

            Task.Factory.StartNew(() =>

            {

                CalculateSum(50);

            });

            Thread.Sleep(3000);

            autoEvent.Set();

            Console.ReadLine();

        }

        public static void CalculateSum(int maxNumber)

        {

            int sum = 0;

            for (int i = 0; i <= maxNumber; ++i)

            {

                sum += i;

            }

            Console.WriteLine("Sum Calculated. Waiting for Main thread to send signal to unblock me");

            autoEvent.WaitOne();

            Console.WriteLine("Sum: " + sum);

        }

    }

}

-----------------------------------------------------------------------------------------------------------------------------

Synchronous execution: doing things one after the other

The user clicks a button and waits for the application to finish handling the click event. Since only

one thing can happen at a time, the UI stops responding until the event has been completely handled. In

the same way, the application can’t do anything in the background while UI is available for user input.

Concurrent: doing multiple things at the same time

The user clicks a button, and the application triggers a separate thread in the background to execute

the task needed to satisfy user’s request concurrently. The thread responsible for handling UI events

becomes available again immediately after starting the background thread, keeping the UI responsive.

Parallel: doing multiple copies of something at the same time

The user instructs the application to process all the files in a folder. The application triggers a

number of threads with the processing logic and distributes the files among these threads.

Asynchronous: not having to wait for one task to finish before starting another

The application starts a database query asynchronously. While the query is in progress, it also starts

reading a file asynchronously. While both tasks are in progress, it does some calculation.

When all these tasks are finished, it uses the results of all these three operations to update the UI.

The execution thread should not wait for an I/O-bound or CPU-bound task to finish.

Examples of I/O-bound operations can be file system access, DB access, or an HTTP request. Examples of CPU-bound operations can be resizing an image, converting a document, or encrypting/decrypting data.

Benefits

Using asynchronous programming has several benefits:

avoiding thread pool starvation by “pausing” execution and releasing the thread back to thread pool

during asynchronous activities

keeping the UI responsive

possible performance gains from concurrency

 

Task-based asynchronous pattern (TAP): RECOMMENDED

We have only an OperationNameAsync method that returns a Task or a generic Task<T> object:

public class MyClass {

    public Task<int> ReadAsync(byte [] buffer, int offset, int count) {...};

}

Task and Task<T> classes model asynchronous operations in TAP. It’s important to understand Task and

Task<T> classes for understanding TAP, which is important for understanding and using async/await

keywords, so let’s talk about these two classes in more detail.

ask and Task<T>

The Task and Task<T> classes are the core of asynchronous programming in .NET. They facilitate all

kinds of interactions with the asynchronous operation they represent, such as:

adding continuation tasks

blocking the current thread to wait until the task is completed

signaling cancellation (via CancellationTokens)

After starting an asynchronous operation and getting a Task or Task<T> object, you can keep using the

current execution thread to asynchronously execute other instructions that don’t need the result of the

task, or interact with the task as needed.

Ex:

using System;

using System.Threading.Tasks;

public class Example {

    public static void Main() {

       Task<DataType> getDataTask = Task.Factory.StartNew(() => { return GetData(); } );

       Task<ProcessedDataType> processDataTask = getDataTask.ContinueWith((data) => { return

ProcessData(data);} );

       Task saveDataTask = processDataTask.ContinueWith((pData) => { SaveData(pData)} );

       Task<string> displayDataTask = processDataTask.ContinueWith((pData) => { return

CreateDisplayString(pData); } );

       Console.WriteLine(displayDataTask.Result);

       saveDataTask.Wait();

    }

}

Almost Good

As demonstrated above, TAP and Task/Task<T> classes are pretty powerful for applying asynchronous

programming techniques. But there’s still room for improvement:

Boilerplate code needed for using tasks is quite verbose.

Assigning continuations and making granular decisions about which task should run means a lot of

details should be handled by the programmer, increasing the complexity and making the code error-prone.

(Verbosity, combined with increased complexity, means the code will be difficult to understand, thus

difficult to maintain.)

Despite all this power, there’s no way to wait for a task to complete without blocking the execution

thread.

These drawbacks can become significant challenges for teams to adopt TAP.

This is where the async and await keywords come into play.

async and await

These keywords have been introduced in response to these challenges of using the Task and Task<T>

classes. They do not represent yet another way of asynchronous programming; they use Task and Task<T>

classes under the hood, simplifying the application of TAP while maintaining the power Task classes

provide to the programmer when needed.

Let’s take a look at each one.

async

The async keyword is added to the method signature to enable the usage of the await keyword in the

method. It also instructs the compiler to create a state machine to handle asynchronicity, but that’s

out of the scope of this article.

The return type of an async method is always Task or Task<T>. It’s checked by the compiler, so there’s

not much room for making mistakes here.

await

The await keyword is used to asynchronously wait for a Task or Task<T> to complete. It pauses the

execution of the current method until the asynchronous task that’s being awaited completes. The

difference from calling.Result or .Wait() is that the await keyword sends the current thread back to

the thread pool, instead of keeping it in a blocked state.
-----------------------------------------------------------------------------------------------------------------------------

How to reverse a given number in C#?

using System;

namespace LogicalPrograms

{

    public class Program

    {

        static void Main(string[] args)

        {

            Console.Write("Enter a Number : ");

            int number = int.Parse(Console.ReadLine());

            int reminder, reverse = 0;

            while (number > 0)

            {

                //Get the remainder by dividing the number with 10 

                reminder = number % 10;

                //multiply the sum with 10 and then add the reminder

                reverse = (reverse * 10) + reminder;

                //Get the quotient by dividing the number with 10

                number = number / 10;

            }

            Console.WriteLine($"The Reverse order is : {reverse}");

            Console.ReadKey();

        }

    }

}

Reverse a String in C# without using Built-in method:

using System;

namespace LogicalPrograms

{

    class Program

    {

        static void Main(string[] args)

        {

            Console.Write("Enter a String : ");

            string originalString = Console.ReadLine();

            string reverseString = string.Empty;

            for (int i = originalString.Length - 1; i >= 0; i--)

            {

                reverseString += originalString[i];

            }

            Console.Write($"Reverse String is : {reverseString} ");

            Console.ReadLine();

        }     

    }

}

Using the for-each loop to reverse a string in C#:

using System;

namespace LogicalPrograms

{

    class Program

    {

        static void Main(string[] args)

        {

            Console.Write("Enter a String : ");

            string originalString = Console.ReadLine();

            string reverseString = string.Empty;

            foreach (char c in originalString)

            {

                reverseString = c + reverseString;

            }

            Console.Write($"Reverse String is : {reverseString} ");

            Console.ReadLine();

        }     

    }

}

///Need one extra array for result, need to traverse full array. 

public static stringReverseString1(string str) { 

    char[] chars = str.ToCharArray(); 

    char[] result = newchar[chars.Length]; 

    for (int i = 0, j = str.Length - 1; i < str.Length; i++, j--) { 

        result[i] = chars[j]; 

    } 

    return new string(result); 

}

----------------------------------------------------------------------------------------------------------------------------------------------------------------------

Swapping two numbers using a third variable in C#:

using System;

namespace LogicalPrograms

{

    public class Program

    {

        public static void Main()

        {

            int number1 = 10, number2 = 20, temp = 0;

            Console.WriteLine($"Before SWapping number1= {number1}, number2 = {number2}");

            temp = number1; //temp=10

            number1 = number2; //number1=20     

            number2 = temp; //number2=10   

            Console.WriteLine($"After swapping number1= {number1}, number2 = {number2}");

            Console.ReadKey();

        }

    }

}

Swap two integers without using the third variable in C#

There are two ways you can use to swap two numbers without using the third variable:

 

By using * and /

By using + and –

using System;

namespace LogicalPrograms

{

    public class Program

    {

        public static void Main()

        {

            int number1 = 10, number2 = 20;

            Console.WriteLine($"Before SWapping number1= {number1}, number2 = {number2}");

            number1 = number1 * number2; //number1=200 (10*20)     

            number2 = number1 / number2; //number2=10 (200/20)     

            number1 = number1 / number2; //number1=20 (200/10)   

            Console.WriteLine($"After swapping number1= {number1}, number2 = {number2}");

            Console.ReadKey();

        }

    }

}

 

 

using System;

namespace LogicalPrograms

{

    public class Program

    {

        public static void Main()

        {

            int number1 = 10, number2 = 20;

            Console.WriteLine($"Before SWapping number1= {number1}, number2 = {number2}");

            number1 = number1 + number2; //number1=30 (10+20)     

            number2 = number1 - number2; //number2=10 (30-20)     

            number1 = number1 - number2; //number1=20 (30-10)   

            Console.WriteLine($"After swapping number1= {number1}, number2 = {number2}");

            Console.ReadKey();

        }

    }

}

The following program swaps two strings without using the third variable in C#.

using System;

namespace LogicalPrograms

{

    public class Program

    {

        public static void Main()

        {

            string name1 = "Dotnet", name2 = "Tutorials";

            Console.WriteLine($"Before SWapping name1= {name1}, name2 = {name2}");

            // Step1: append 2nd string with the 1st string

            name1 = name1 + name2;

            //Step2: store intial string name1 in string name2

            name2 = name1.Substring(0, name1.Length - name2.Length);

            //Step3:  store initial string name2 in string name1

            name1 = name1.Substring(name2.Length);

  

            Console.WriteLine($"After swapping name1= {name1}, name2 = {name2}");

            Console.ReadKey();

        }

    }

}
----------------------------------------------------------------------------------------------------------------------------------------------------------------------

How to check if a given number is prime or not in C#?

The following example takes one input from the console and then checks whether that number is a prime number or not.

 

using System;

namespace LogicalPrograms

{

    public class Program

    {

        static void Main(string[] args)

        {

            Console.Write("Enter a Number : ");

            int number = int.Parse(Console.ReadLine());

            bool IsPrime = true;

            for (int i = 2; i < number/2; i++)

            {

                if (number % i == 0)

                {

                    IsPrime = false;

                    break;

                }

            }

            if (IsPrime)

            {

                Console.Write("Number is Prime.");

            }

            else

            {

                Console.Write("Number is not Prime.");

            }

            Console.ReadKey();

        }

    }

}

 

How to display Prints the Prime Numbers between a range of numbers in C#?

In the following example, we will take two numbers from the console and then print the prime numbers present between those two numbers.

 

using System;

namespace LogicalPrograms

{

    public class Program

    {

        static void Main(string[] args)

        {

            Console.Write("Enter The Start Number: ");

            int startNumber = int.Parse(Console.ReadLine());

            Console.Write("Enter the End Number : ");

            int endNumber = Convert.ToInt32(Console.ReadLine());

            Console.WriteLine($"The Prime Numbers between {startNumber} and {endNumber} are : ");

            for (int i = startNumber; i <= endNumber; i++)

            {

                int counter = 0;

                for (int j = 2; j <= i / 2; j++)

                {

                    if (i % j == 0)

                    {

                        counter++;

                        break;

                    }

                }

                if (counter == 0 && i != 1)

                {

                    Console.Write("{0} ", i);

                }   

            }

            Console.ReadKey();

        }

    }

}
----------------------------------------------------------------------------------------------------------------------------------------------------------------------

How to check if a given number is Palindrome or not in C#?

Algorithm to check Palindrome Number in C#:

 

First, get the number from the user which you want to check

Hold that number in a temporary variable

Reverse that number

Compare the temporary number with the reversed number

If both numbers are the same, then print it is a palindrome number else print it is not a palindrome number

Example: Palindrome Number Program in C#

The following C# Program will allow the user to input a number and then checks whether that number is a Palindrome Number or not.

 

using System;

namespace LogicalPrograms

{

    public class Program

    {

        static void Main(string[] args)

        {

            Console.Write("Enter a Number To Check Palindrome : ");

            int number = int.Parse(Console.ReadLine());

            int remineder, sum = 0;

            int temp = number;

            while (number > 0)

            {

                //Get the remainder by dividing the number with 10 

                remineder = number % 10;

                //multiply the sum with 10 and then add the remainder

                sum = (sum * 10) + remineder;

                //Get the quotient by dividing the number with 10

                number = number / 10;

            }

            if (temp == sum)

            {

                Console.WriteLine($"Number {temp} is Palindrome.");

            }

            else

            {

                Console.WriteLine($"Number {temp} is not Palindrome");

            }

            Console.ReadKey();

        }

    }

}

Output:

How to check if a given number is Palindrome or not?

 

How to check if a given string is Palindrome or not in C#?

In the following program, we take the string as an input from the console. Then we reverse the string using for loop and storing the reverse string value in the reverse variable. Finally, we check whether the original and reverse values are the same or not. If both are the same then the string is Palindrome else it is not Palindrome.

 

using System;

namespace LogicalPrograms

{

    public class Program

    {

        static void Main(string[] args)

        {

            Console.Write("Enter a string to Check Palindrome : ");

            string name = Console.ReadLine();

            string reverse = string.Empty;

           

            for (int i = name.Length - 1; i >= 0; i--)

            {

                reverse += name[i];

            }

           

            if (name == reverse)

            {

                Console.WriteLine($"{name} is Palindrome.");

            }

            else

            {

                Console.WriteLine($"{name} is not Palindrome");

            }

            Console.ReadKey();

        }

    }

}

 

Using the for-each loop:

using System;

namespace LogicalPrograms

{

    public class Program

    {

        static void Main()

        {

            Console.Write("Enter a string to Check Palindrome : ");

            string name = Console.ReadLine();

            string reverse = string.Empty;

            foreach (char c in name)

            {

                reverse = c + reverse;

            }

            if (name.Equals(reverse, StringComparison.OrdinalIgnoreCase))

            {

                Console.WriteLine($"{name} is Palindrome");

            }

            else

            {

                Console.WriteLine($"{name} is not Palindrome");

            }

            Console.ReadKey();

        }

    }

}
----------------------------------------------------------------------------------------------------------------------------------------------------------------------

Factorial Number Program in C# using for loop:

 

 

using System;

namespace LogicalPrograms

{

    class Program

    {

        static void Main(string[] args)

        {

            Console.Write("Enter a Number : ");

            int number = int.Parse(Console.ReadLine());

            int factorial = 1;

            for (int i = 1; i <= number; i++)

            {

                factorial = factorial * i;

            }

            Console.Write($"Factorial of {number}  is: {factorial}");

           

            Console.ReadLine();

        }

    }

}

 

 

 

Factorials of a number using while loop in C#:

 

using System;

namespace LogicalPrograms

{

    class Program

    {

        static void Main(string[] args)

        {

            Console.Write("Enter a Number : ");

            int number = int.Parse(Console.ReadLine());

            long factorial = 1;

            while (number != 1)

            {

                factorial = factorial * number;

                number = number - 1;

            }

           

            Console.Write($"Factorial is: {factorial}");          

            Console.ReadLine();

        }

    }

}

 

Factorial of a number using Recursive Function in C#:

 

using System;

namespace LogicalPrograms

{

    class Program

    {

        static void Main(string[] args)

        {

            Console.Write("Enter a Number : ");

            int number = int.Parse(Console.ReadLine());

            long factorial = RecursiveFactorial(number);

            Console.Write($"Factorial of {number} is: {factorial}");   

           

            Console.ReadLine();

        }

        static long RecursiveFactorial(int number)

        {

            if (number == 1)

            {

                return 1;

            }

            else

            {

                return number * RecursiveFactorial(number - 1);

            }   

        }

    }

}

 

 

Factorial of a number using the do-while loop in C#:

 

using System;

namespace LogicalPrograms

{

    class Program

    {

        static void Main(string[] args)

        {

            Console.Write("Enter a Number : ");

            int number = int.Parse(Console.ReadLine());

            long factorial =  1;

            do

            {

                factorial = factorial * number;

                number--;

            } while (number > 0);

            Console.Write($"The Factorial is: {factorial}");

            Console.ReadLine();

        }     

    }

}
----------------------------------------------------------------------------------------------------------------------------------------------------------------------

Armstrong Number Program in C# with Examples

using System;

namespace LogicalPrograms

{

    class Program

    {

        static void Main(string[] args)

        {

            int i = 0;

            int digitCount = 0;

            int[] digitArray = new int[10];

            double sum = 0;

            //Step1: Take the input

            Console.Write("Enter the Number : ");

            int number = int.Parse(Console.ReadLine());

            //Step3: Store the number in a temporary variable

            int temporaryNumber = number;

            //Step3: Find the total number of digits in number as well as

            //Store each each digit in the digit array

            while (number > 0)

            {

                digitArray[i++] = number % 10;

                number = number / 10;

                digitCount++;

            }

            //Step4: Calculate the result

            for (i = 0; i < digitCount; i++)

            {

                sum += Math.Pow(digitArray[i], digitCount);

            }

            //Step5: Check whether it is prime number or not

            if (sum == temporaryNumber)

            {

                Console.WriteLine($"The Number {temporaryNumber} is armstrong");

            }

            else

            {

                Console.WriteLine($"The Number {temporaryNumber} is not armstrong");

            }

            Console.ReadLine();

        }

    }

}

Output:

Armstrong Number in C#

 

Finding Armstrong number between ranges of numbers in C#:

 

using System;

namespace LogicalPrograms

{

    class Program

    {

        static void Main(string[] args)

        {

            Console.Write("Enter the Start Number : ");

            int StartNumber = int.Parse(Console.ReadLine());

            Console.Write("Enter the End Number : ");

            int EndNumber = int.Parse(Console.ReadLine());

            Console.WriteLine($"The Armstrong Numbers between {StartNumber} and {EndNumber} are : ");

            for (int i = StartNumber; i <= EndNumber; i++)

            {

                if (IsArmstrongNumber(i))

                    Console.WriteLine(i);

            }

           

            Console.ReadLine();

        }

        static bool IsArmstrongNumber(int number)

        {

            int sum = 0;

            int temporaryNumber = number;

            int temp = 0;

            int length = number.ToString().Length;

            while (number != 0)

            {

                temp = number % 10;

                number = number / 10;

                sum += (int)Math.Pow(temp, length);

            }

           

            if (sum == temporaryNumber)

            {

                return true;

            }

            else

            {

                return false;

            }

        }

    }

}
----------------------------------------------------------------------------------------------------------------------------------------------------------------------

Algorithm: Sum of Digits Program in C#

 

using System;

namespace LogicalPrograms

{

    public class Program

    {

        static void Main(string[] args)

        {

            Console.Write("Enter the Number : ");

            int number = int.Parse(Console.ReadLine());

            int sum = 0, reminder;

          

            while (number > 0)

            {

                reminder = number % 10;

                sum = sum + reminder;

                number = number / 10;

            }

           

            Console.WriteLine($"The Sum of Digits is : {sum}");

            Console.ReadKey();

        }

    }

}

 

Finding the sum of digits of a given number using a loop in C#

 

 

using System;

namespace LogicalPrograms

{

    public class Program

    {

        static void Main(string[] args)

        {

            Console.Write("Enter the Number : ");

            int number = int.Parse(Console.ReadLine());

            int sum = SumOfDigits(number);

            Console.WriteLine($"The Sum of Digits is : {sum}");

            Console.ReadKey();

        }

        static int SumOfDigits(int number)

        {

            if (number != 0)

            {

                return (number % 10 + SumOfDigits(number / 10));

            }

            else

            {

                return 0;

            }

        }

    }

}

 

 

Using Linq to find the sum of digits of a number in C#:

 

using System;

using System.Linq;

namespace LogicalPrograms

{

    public class Program

    {

        static void Main(string[] args)

        {

            Console.Write("Enter the Number : ");

            int number = int.Parse(Console.ReadLine());

           

            int sum = number.ToString().Select(digit => int.Parse(digit.ToString())).ToArray().Sum();

           

            Console.WriteLine($"The Sum of Digits is : {sum}");

            Console.ReadKey();

        }

    }
----------------------------------------------------------------------------------------------------------------------------------------------------------------------








 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 























No comments:

Post a Comment

TypeScript