You are on page 1of 68

Contents

Part 1 - Introduction................................................................................................................................. 4
Part 2 - Reading and writing to a console ........................................................................................ 4
Part 3 - Built - in types .............................................................................................................................. 4
Part 4 - String type.................................................................................................................................... 4
Part 5 - Common Operators ................................................................................................................. 4
Part 6 - Nullable Types ............................................................................................................................ 5
Part 7 - Datatypes conversion .............................................................................................................. 5
Part 8 - Arrays ............................................................................................................................................ 5
Part 9 - Comments ................................................................................................................................... 5
Part 10 - If statement ............................................................................................................................... 5
Part 11 - switch statement ..................................................................................................................... 5
Part 16 - Methods ..................................................................................................................................... 5
Part 17 - Method parameters ............................................................................................................... 5
Part 18 - Namespaces ............................................................................................................................ 7
Part 19 Introduction to Classes.......................................................................................................... 8
Part 20 - Static and instance class members ................................................................................. 10
Part 21 - Inheritance .............................................................................................................................. 12
Part 22 - Method hiding ....................................................................................................................... 14
Part 23 - Polymorphism ......................................................................................................................... 15
Part 24 - Difference between method overriding and method hiding ................................. 21
Part 25 - Method overloading ............................................................................................................ 21
Part 26 - Why Properties ....................................................................................................................... 22
Part 27 Properties ................................................................................................................................ 23
Part 28 Structs....................................................................................................................................... 24
Part 29 - Difference between classes and structs ........................................................................ 25
Part 30 - Interfaces................................................................................................................................. 27
Part 31 - Explicit interfaces implementation ................................................................................... 29
Part 32 - Abstract classes ..................................................................................................................... 30
Part 33 - Difference between abstract classes and interfaces ................................................ 31
Part 34 - Problems of multiple class inheritance............................................................................ 32
Part 35 - Multiple class inheritance using interfaces .................................................................... 33
Part 36 - Delegates ................................................................................................................................ 33
Part 37 - Delegates usage ................................................................................................................... 34
Part 38 - Delegates usage continued .............................................................................................. 34
Part 39 - Multicast Delegates.............................................................................................................. 35
Part 40 - Exception Handling .............................................................................................................. 36
Part 41 - Inner Exceptions .................................................................................................................... 37
Part 42 - Custom Exceptions ............................................................................................................... 38
Part 43 - Exception handling abuse ................................................................................................. 39
Part 44 - Preventing exception handling abuse ........................................................................... 40
Part 45 - Why Enums .............................................................................................................................. 41
Part 46 - Enums Example ...................................................................................................................... 41
Part 47 Enums ....................................................................................................................................... 41
Part 48 - Difference between Types and Type Members ........................................................... 43
Part 49 - Access Modifiers Private, Public & Protected ............................................................ 44
Part 50 - Access Modifiers Internal and Protected Internal .................................................... 44
Part 51 - Access Modifiers for types .................................................................................................. 45
Part 52 - Attributes ................................................................................................................................. 45
Part 53 - Reflection ................................................................................................................................ 46
Part 54 - Reflection Example............................................................................................................... 48
Part 55 - Late binding using reflection ............................................................................................. 48
Part 56 Generics .................................................................................................................................. 49
Part 57 - Why should you override ToString Method .................................................................... 50
Part 58 - Why should you override Equals Method ...................................................................... 50
Part 59 - Difference between Convert.ToString and ToString ................................................... 51
Part 60 - Difference between String and StringBuilder ................................................................ 52
Part 61 - Partial classes ......................................................................................................................... 53
Part 62 - Creating partial classes ....................................................................................................... 54
Part 63 - Partial methods ...................................................................................................................... 55
Part 64 - How and where are indexers used in .net ..................................................................... 56
Part 65 - Indexers .................................................................................................................................... 58
Part 66 - Overloading indexers........................................................................................................... 58
Part 67 - Optional parameters ........................................................................................................... 58
Part 68 - Making method parameters optional using method overloading ........................ 58
Part 69 - Making method parameters optional by specifying parameter defaults ........... 58
Part 70 - Making method parameters optional by using OptionalAttribute......................... 58
Part 71 - Code snippets in visual studio ........................................................................................... 58
Part 72 - What is dictionary.................................................................................................................. 58
Part 73 - What is dictionary continued ............................................................................................ 58
Part 74 - List collection class ................................................................................................................ 59
Part 75 - List collection class continued........................................................................................... 59
Part 76 - Working with generic list class and ranges .................................................................... 59
Part 77 - Sort a list of simple types ..................................................................................................... 59
Part 78 - Sort a list of complex types ................................................................................................. 59
Part 79 - Sort a list of complex types using Comparison delegate .......................................... 59
Part 80 - Some useful methods of List collection class ................................................................ 59
Part 81 - When to use a dictionary over list .................................................................................... 59
Part 82 - Generic queue collection class ........................................................................................ 59
Part 83 - Generic stack collection class .......................................................................................... 59
Part 84 - Real time example of queue collection class .............................................................. 59
Part 85 - Real time example of stack collection class ................................................................. 59
Part 86 - Multithreading ........................................................................................................................ 60
Part 87 - Advantages and disadvantages of multithreading ................................................... 60
Part 88 - ThreadStart delegate ........................................................................................................... 60
Part 89 - ParameterizedThreadStart delegate .............................................................................. 60
Part 90 - Passing data to the Thread function in a type safe manner.................................... 60
Part 91 - Retrieving data from Thread function using callback method ............................... 60
Part 92 - Significance of Thread Join and Thread IsAlive functions ......................................... 60
Part 93 - Protecting shared resources from concurrent access in multithreading.............. 60
Part 94 - Difference between Monitor and lock ........................................................................... 60
Part 95 - Deadlock in a multithreaded program .......................................................................... 60
Part 96 - How to resolve a deadlock in a multithreaded program ......................................... 60
Part 97 - Performance of a multithreaded program ................................................................... 60
Part 98 - Anonymous methods ........................................................................................................... 60
Part 99 - Lambda expression .............................................................................................................. 61
Part 100 - Func delegate ..................................................................................................................... 61

Part 1 - Introduction
.Net we have deployed multiple application,
- Web - Console - Sharepoint
- Office - Window - WebService
Console Application: This is nothing but commend prompt.
1. Create Console Application
2. Write Simple Program, Console can be called inside the System
using System;
class SampleProgram
{
public static void Main()
{
Console.WriteLine("Welcome");
}
}
Using Declaration: A namespace is used to organize your code and is collection of
1. Class Instance & Static class
2. Interface
3. Structs
4. Enum
5. Delegates
Main method is the entry point of the code-behind application,
Every console application should have Main() function, & its an entry point to run
application.
using System;
class SampleProgram
{
public static void Main1()
{
Console.WriteLine("Welcome Inner Function");
}
public static void Main()
{ //the list of function should called only if we declare inside Main()
Console.WriteLine("Welcome");
Main1();
}
}
Part 2 - Reading and writing to a console
In a program
Part 3 - Built - in types
In a program
Part 4 - String type
In a program
Part 5 - Common Operators
In a program
Part 6 - Nullable Types
In a program
Part 7 - Datatypes conversion
In a program
Part 8 - Arrays
In a program
Part 9 - Comments
In a program
Part 10 - If statement
In a program
Part 11 - switch statement
In a program
Part 16 - Methods
Instance/Non-Static Method Static Method
1. Instance methods are methods that 1. Static methods are methods that are
are associated with objects of a class associated with a class
2. When no static modifier presents that 2. Method declaration includes a static
method called as instance class modifier called static class
3. Instance method involved using an 3. Static method involved using the class
instance of the class name
4. If multiple instances of the class can be 4. In method of static, there are no
created/initiated and each instance instances of that method, and you can
has its own separate method. invoke only that one definition of the
5. Instance method usually possesses a static method
reference to the object that called the 5. this keyword cannot be used in static
method and it can be accessed using methods since they are not associated
the this keyword inside the method with a particular object
class Program class Program
{ {
public static void Main() public static void Main()
{ {
Program p = new Program(); Program.EvenNumber(50);
int Sum = p.Add(10, 20); }
Console.WriteLine("Total count: {0}", Sum); public static void EvenNumber(int Target)
} {
public int Add(int FN, int SN) int intStart = 0;
{ while (intStart <= Target)
return FN + SN; {
} Console.WriteLine(intStart);
} intStart = intStart + 2;
}
}
}

Part 17 - Method parameters val, ref, out


4 types of method parameters
1. Value Parameters
2. Reference Parameters
3. Out Parameters
4. Parameter Arrays

Output Parameter:
Use when you want a method to return more than one value.
class Program
{
public static void Main()
{
int Total = 0;
int Product = 0;
Calculator(10, 20, out Total, out Product);
Console.WriteLine("Total: {0}, Product: {1}", Total, Product);
}
public static void Calculator(int FN, int SN, out int Sum, out int Product)
{
Sum = FN + SN;
Product = FN * SN;
}
}
Output: Total: 30, Product: 200
Parameter Arrays:
The params keyword lets you specify a method parameter that takes a variable number
of arguments. You can send a comma-separated list of arguments, or an array, or no
arguments.
Params keyword should be the last one in the method declaration (e.g., public static
void ParameterMtd(int i, int j, params int[] Numbers) ),and only one params
keyword is permitted in a method declaration. (e.g., Not allowed - public static void
ParameterMtd(params string[] Name, params int[] Numbers))

class Program
{
public static void Main()
{
int[] Numbers = new int[3];
Numbers[0] = 12;
Numbers[1] = 13;
Numbers[2] = 14;
//ParameterMtd();
//ParameterMtd(Numbers);
ParameterMtd(1, 2, 3, 4, 5); //Method Argument
}
/*Parameter allows null argument only if params used*/
public static void ParameterMtd(params int[] Numbers) //Method Parameter
{
Console.WriteLine("There are {0} elements in an Array", Numbers.Length);
foreach (int i in Numbers)
{
Console.WriteLine(i);
}
}
}
Output ParameterMtd(1, 2, 3, 4, 5);
ParameterMtd(); There are 5 elements in an Array
There are 0 elements in an Array 1
ParameterMtd(Numbers); 2
There are 3 elements in an Array 3
12 4
13 5
14
Part 18 Difference b/w value and Reference Parameter

Value Parameter Reference Parameter


Creates a copy of the parameter passed, so The ref method parameter keyword on a
modifications does not affect each other. method parameter causes a method to refer to
the same variable that was passed into the
method. Any changes made to the parameter
in the method will be reflected in that variable
when control passes back to the calling
method.

class Program class Program


{ {
public static void Main() public static void Main()
{ {
int i = 0; int i = 0;
mtdAssign(i); //this way also we pass- mtdAssign(ref i); //this way also we pass-
Program.mtdAssign(i); Program.mtdAssign(i);
Console.WriteLine("Return Value {0}", i); Console.WriteLine("Return Value {0}", i);
} }
public static void mtdAssign(int j) public static void mtdAssign(ref int j)
{ {
j = 101; j = 101;
} }
} }
Output: 0 Output: 101

Part 18 - Namespaces
Why Namespace? Namespaces are used to organize your programs. They also provide
assistance in avoiding name clashes.
Namespace dont corresponding to file, directory or assembly names. They could be written in
separate files and / or separate assemblies and still belongs to same namespace.
Namespace can be nested in 2 ways.
Namespace alias directives. Sometimes you may encounter a long namespace and wish to
have it shorter. This could improve readability and avoid name clashes with similarly named
methods.
fully qualified name
alias directives
using PATA = ProjectA.TeamA;
using PATB = ProjectB.TeamA;
class Program
{
public static void Main()
{
PATA.ClassA.Print();
PATB.classA.Print();
}
}
namespace ProjectA
{
namespace TeamA
{
class ClassA
{
public static void Print()
{
Console.WriteLine("Testing Project A --> Team A --> Class A");
}
}
}
}
namespace ProjectB
{
namespace TeamA
{
class classA
{
public static void Print()
{
Console.WriteLine("Testing Project B -->Team A --> Class A");
}
}
}
}
Avoid ambiguity using fully qualified name

Avoid ambiguity using alias directives A namespaces can contains


1. Another namespace
2. Class
3. Interface
4. Struct
5. Enum
6. Delegate

Part 19 Introduction to Classes


So far we have seen simple datatypes like int, float, double etc. If you want to create
complex custom types, then we can make use of classes.
A class contains of data and behavior. Class Data is representing its fields and behavior is
represented by its methods.
Class can have Constructor, Method and Destructor
Constructor Method Destructor
same name as class different name same name as class
They do take parameter They do take parameter They do not take parameter
Do not have returntype Do have returntype does not have returntype and
have ~ symbol in front of them
Destructors:
Destructors have the same name as class with ~ symbol in front of them.
They dont take any parameters and do not return a value.
Destructors are places where you could put code to release any resources your class
was holding during its lifetime. Usually c# doesnt require destructor. They are normally
called when the C# garage collector decides to clean your project from memory.

this refer the instance / object of the class


Access modifier public

Is it mandatory to pass constructor in class. No its not required.


If we wont pass the constructor c# provide less parameter constructor.
E.g., Customer C1 = new Customer();
using System;
class Consumer
{
string _firstName { get; set; }
string _lastName { get; set; }
public Consumer()//this is optional, if we do not declare, class will take default
parameter less constructor
: this("No FirstName provided", "No LastName provided")
{
}
public Consumer(string FirstName, string LastName)
{
this._firstName = FirstName;
this._lastName = LastName;
}

public void PrintFullName()


{
Console.WriteLine("Full Name {0}:", this._firstName + " " + this._lastName);
}
~Consumer()
{
//clean up code
}
}
class Program
{
public static void Main()
{
//if we declare like with or without parameter called as overloading a constructor by
their type of parameters
Consumer C1 = new Consumer();
C1.PrintFullName();

Consumer C2 = new Consumer("Sathya", "Kulandhaivel");


C2.PrintFullName();
}
}

O/P: Full Name: No FirstName provided No LastName provided


Full Name: Sathya Kulandhaivel

Purpose of a class constructor:


The purpose of class constructor is to initialize class fields. A class constructor is
automatically called when an instance of a class is created.
Constructors do not have return values and always have the same name as the class.
Constructors are not mandatory. If we do not provide a constructor, a default parameter
less constructor is automatically provided.
Constructors can be overloaded by the number and type of parameters.

Part 20 - Static and instance class members


This represent the object of the instance class
using System;
class Circle
{ O/P:
float _Pi = 3.14F; Area of the Circle:78.5
int _Radius;
public Circle(int Radius) Area of the Circle:113.04
{
this._Radius = Radius;
} For above program for to calculate
public float CalculateArea() the Area of circle, the Pi value can
{
return this._Pi * this._Radius * this._Radius;
be change, it means that is non-
} static/instance fields.
} If we want to make it as static field,
class Program
just want to add static keyword
{
public static void Main() infornt of field i.e. static float _Pi =
{ 3.14F;
Circle C1 = new Circle(5); Static keyword not only used in field,
float Area1 = C1.CalculateArea();
Console.WriteLine("Area of the Circle:" but also properties, methods,
+ Area1); constructors, events, delegates
etc.,all type called as members. If
Circle C2 = new Circle(6);
float Area2 = C2.CalculateArea();
this members declared as static
Console.WriteLine("Area of the Circle:" infront of declaration called as
+ Area2); static-members
}
}
Static Contructor should not have
access-modifier and declare
before the Instance Constructor.

Non-Static/Instance Member Static Member


When no static modifier is present in the member is When a class member includes a static
called as non-static member or instance member modifier, the member is called as static
member
Its invoked using instances (objects) of the class. Its invoked using class name.
Instance member belongs to specific instance Whereas there will be only one copy of a
(object) of a class. If I create 3 objects of a class, I static member, no matter how many
will have 3 sets of instance members in the memory. instances of a class are created.

Note: Class members field, methods, properties, events, indexes, constructors.


Constructors:
Static constructors are used to initialize static fields in a class.
You declare a static constructor by using the keyword static in front of the constructor
name.
Static Constructor is called only one, no matter how many instances you create.
Static constructors are called before instance constructors.

using System; O/P


class Circle
{ Static Constructor Class
public static float _Pi; Called
int _Radius; Main method class called
static Circle()
{ 3.14
Console.WriteLine("Static Constructor Class Called"); Instance Constructor Class
Circle._Pi = 3.14F; Called
}
public Circle(int Radius)
Area Value 50.24.
{
Console.WriteLine("Instance Constructor Class Called");
this._Radius = Radius;
}
public float CalculateArea()
{
return Circle._Pi* this._Radius * this._Radius;
}
}
class Program
{
public static void Main()
{
Console.WriteLine("Main method class called {0}", Circle._Pi);
Circle C1 = new Circle(4);
float Area = C1.CalculateArea();
Console.WriteLine("Area Value {0}", Area);
}
}

Part 21 - Inheritance
Why Inheritance: A lot of code between these 2 classes is duplicate
using System;
public class Employee
{ O/P:
public string FirstName; Full Name: Full, Time
public string LastName; Salary: 50000
public string email;
public void PrintFullName()
Full Name: Part, Time
{ Salary: 60000
Console.WriteLine("Full Name: {0}, {1}", FirstName, LastName);
}
}
public class FullTimeEmployee : Employee
{
public float MonthlySalary;
}
public class PartTimeEmployee: Employee
{
public float HourlyRate;
}
class Program
{
public static void Main()
{
FullTimeEmployee FTE = new FullTimeEmployee();
FTE.FirstName = "Full";
FTE.LastName = "Time";
FTE.MonthlySalary = 50000;
FTE.PrintFullName();
Console.WriteLine("Salary: {0}", FTE.MonthlySalary);
PartTimeEmployee PTE = new PartTimeEmployee();
PTE.FirstName = "Part";
PTE.LastName = "Time";
PTE.HourlyRate = 60000;
PTE.PrintFullName();
Console.WriteLine("Salary: {0}", PTE.HourlyRate);
}
}

Pillars of OOPs:
1. Inheritance
2. Encapsulation
3. Abstraction
4. Polymorphism
Inheritance is one of the primary pillars of OOP.
It allows code reuse.
Code reuse can reduce time and errors.

Note: You will specify all the common fields, properties, methods in the base class, which allows
reusability. In the derived class you will only have fields, properties and methods, which are
specific to them.

Inheritance Syntax
1. In this example DerivedClass inherits from ParentClass.
2. C# supports only single class inheritance.

3. C# supports multiple interface inheritance.

4. Child class is a specialization of base class.


5. Base classes are automatically instantiated before derived classes.
6. Parent class constructor executes before child class constructor.
using System;
public class ParentClass
{
public ParentClass()
{
Console.WriteLine("ParentClass Constructor Called");
}
public ParentClass(string strMessage)
{
Console.WriteLine("ParentClass with Message Parameter Constructor:" + strMessage );
}
}
public class ChildClass : ParentClass
{
/* if we pass 2 constructor - ParentClass() Or ParentClass(string strMessage)
if 'base' is not declare C# automatically prefer less parameter constructor.
It means - ParentClass() */
public ChildClass() : base("C Testing")
{
Console.WriteLine("ChildClass Constructor Called");
}
}
class Program
{
public static void Main()
{
//always C# first call ParentClass & then ChildClass
ChildClass CC = new ChildClass();
}
}
O/P:
ParentClass with Message Parameter Constructor:C Testing
ChildClass Constructor Called

Part 22 - Method hiding


Use the new keyword to hide a base class member. You will get a compiler warning, if you miss
the new keyword.
Different ways to invoke a hidden base class member from derived class
1. Use base keyword.
2. Case child type to parent type and invoke the hidden member.
3. ParentClass PC = new ChildClass()
PC.HiddenMethod()

using System; O/P:


public class Employee
{ Full Time
public string FirstName; Part Time
public string LastName;
public string email;
public void PrintFullName()
{
Console.WriteLine(FirstName + " " + LastName);
}
}
public class PartTimeEmployee : Employee
{
public new void PrintFullName()
{
base.PrintFullName(); //Used to call the hidden base class
//Console.WriteLine(FirstName + " " + LastName + " - Contractors");
}
}
public class FullTimeEmployee : Employee
{
}
class Program
{
public static void Main()
{
FullTimeEmployee FTE = new FullTimeEmployee();
FTE.FirstName = "Full";
FTE.LastName = "Time";
FTE.PrintFullName();
Employee PTE = new PartTimeEmployee();
PTE.FirstName = "Part";
PTE.LastName = "Time";
//PTE.PrintFullName();
((Employee)PTE).PrintFullName();
}
}

Part 23 - Polymorphism
Polymorphism is one of the primary pillars of OOP.
Polymorphism allows you to invoke derived class methods through a base class reference
during runtime.
In the base class the method is declared virtual, and in the derived class we override the
same method.
The virtual keyword indicates, the method can be overridden in any derived class.
using System; O/P:
public class Employee FN LN
{
FN LN - PartTime Employee
public string FName = "FN";
public string LName = "LN"; FN LN - FullTime Employee
public virtual void PrintFullName() FN LN - Temporary Employee
{
Console.WriteLine(FName + " " + LName);
}
}
public class PartTimeEmployee : Employee
{
public override void PrintFullName()
{
Console.WriteLine(FName + " " + LName + " - PartTime Employee");
}
}
public class FullTimeEmployee : Employee
{
public override void PrintFullName()
{
Console.WriteLine(FName + " " + LName + " - FullTime Employee");
}
}
public class TemporaryEmployee : Employee
{
public override void PrintFullName()
{
Console.WriteLine(FName + " " + LName + " - Temporary Employee");
}
}
class Program
{
public static void Main()
{
Employee[] arrEmp = new Employee[4];
arrEmp[0] = new Employee();
arrEmp[1] = new PartTimeEmployee();
arrEmp[2] = new FullTimeEmployee();
arrEmp[3] = new TemporaryEmployee();

foreach (Employee arr in arrEmp)


{
arr.PrintFullName();
}

}
}
Polymorphism simply means 'many forms'. After encapsulation and inheritance,
polymorphism plays a major role in object-oriented programming.
In other words, polymorphism means the states or behaviors of an object such as emotions
of a person.

There are two types of polymorphism. They are,


Static Polymorphism
- Method overloading and Operator overloading are the examples.
Dynamic Polymorphism
- Method overriding and Virtual functions are the examples.
Above diagram shows the brief architecture of polymorphism in object-oriented
programming.

Part 22 Encapsulation
Encapsulation is defined 'as the process of enclosing one or more items within a physical or
logical package'. Encapsulation, in object oriented programming methodology, prevents
access to implementation details.

Abstraction and encapsulation are related features in object oriented programming.


Abstraction allows making relevant information visible and encapsulation enables a
programmer to implement the desired level of abstraction.

Encapsulation is implemented by using access specifiers. An access specifier defines the


scope and visibility of a class member. C# supports the following access specifiers:

Public
Private
Protected
Internal
Protected internal
Public Access Specifier

Public access specifier allows a class to expose its member variables and member functions to
other functions and objects. Any public member can be accessed from outside the class.

The following example illustrates this:


using System; //member variables
namespace RectangleApplication public double length;
{ public double width;
class Rectangle
{ public double GetArea()
{ {
static void Main(string[] args)
return length * width;
{
}
Rectangle r = new Rectangle();
public void Display()
r.length = 4.5;
{
r.width = 3.5;
Console.WriteLine("Length: {0}", length);
r.Display();
Console.WriteLine("Width: {0}", width);
Console.ReadLine();
Console.WriteLine("Area: {0}", GetArea());
}
}
}
}//end class Rectangle
}
class ExecuteRectangle

When the above code is compiled and executed, it produces the following result:
Length: 4.5
Width: 3.5
Area: 15.75

In the preceding example, the member variables length and width are declared public, so they
can be accessed from the function Main() using an instance of the Rectangle class, named r.

The member function Display() and GetArea() can also access these variables directly without
using any instance of the class.

The member functions Display() is also declared public, so it can also be accessed
from Main() using an instance of the Rectangle class, named r.
Private Access Specifier

Private access specifier allows a class to hide its member variables and member functions
from other functions and objects. Only functions of the same class can access its private
members. Even an instance of a class cannot access its private members.

The following example illustrates this:


using System; Console.WriteLine("Enter Console.WriteLine("Area: {0}",
namespace RectangleApplication
Width: "); GetArea());
{ width = }
class Rectangle Convert.ToDouble(Console.ReadLi }//end class Rectangle
{ ne());
//member variables } class ExecuteRectangle
private double length; public double GetArea() {
private double width; { static void Main(string[] args)
return length * width; {
public void Acceptdetails() } Rectangle r = new Rectangle();
{ public void Display() r.Acceptdetails();
Console.WriteLine("Enter { r.Display();
Length: "); Console.WriteLine("Length: Console.ReadLine();
length = {0}", length); }
Convert.ToDouble(Console.ReadLi Console.WriteLine("Width: }
ne()); {0}", width); }
When the above code is compiled and executed, it produces the following result:
Enter Length:
4.4
Enter Width:
3.3
Length: 4.4
Width: 3.3
Area: 14.52

In the preceding example, the member variables length and width are declaredprivate, so
they cannot be accessed from the function Main(). The member
functions AcceptDetails() and Display() can access these variables. Since the member
functions AcceptDetails() and Display() are declared public, they can be accessed
from Main() using an instance of the Rectangle class, named r.
Protected Access Specifier

Protected access specifier allows a child class to access the member variables and member
functions of its base class. This way it helps in implementing inheritance. We will discuss this
in more details in the inheritance chapter.
Internal Access Specifier

Internal access specifier allows a class to expose its member variables and member functions
to other functions and objects in the current assembly. In other words, any member with
internal access specifier can be accessed from any class or method defined within the
application in which the member is defined.

The following program illustrates this:


using System; public void Display() static void Main(string[] args)
namespace RectangleApplication { {
{ Console.WriteLine("Length: Rectangle r = new Rectangle();
class Rectangle {0}", length); r.length = 4.5;
{ Console.WriteLine("Width: r.width = 3.5;
//member variables {0}", width); r.Display();
internal double length; Console.WriteLine("Area: {0}", Console.ReadLine();
internal double width; GetArea()); }
} }
double GetArea() }//end class Rectangle }
{
return length * width; class ExecuteRectangle
} {

When the above code is compiled and executed, it produces the following result:
Length: 4.5
Width: 3.5
Area: 15.75
In the preceding example, notice that the member function GetArea() is not declared with any
access specifier. Then what would be the default access specifier of a class member if we don't
mention any? It is private.
Protected Internal Access Specifier

The protected internal access specifier allows a class to hide its member variables and
member functions from other class objects and functions, except a child class within the same
application. This is also used while implementing inheritance.

Difference b/w Method Encapsulation and Abstraction


Encapsulation Abstraction
Wrapping up of data and methods into a single It is an act of representing only the essential things
unit is Encapsulation (e.g. Class) without including background details. (e.g.
Interface)

Part 23 Difference b/w Method Overloading and Overriding


Method Overloading Method Overriding
1. Overloading (Called as Early Binding or 1. Overriding (Called as Late
Compile Time Polymorphism or static Binding or Run Time
binding) Polymorphism or dynamic
2. Creating a multiple methods in a class binding)
with same name but different parameters 2. Creating the method in a
and types is called as method derived class with same name,
overloading. parameters and return type as in
3. Method overloading can be achieved by base class is called as method
using following things : overriding.
By changing the number of parameters 3. Some Key Points of Method
used. overriding
By changing the order of parameters. Method overriding is only
By using different data types for the possible in derived class not
parameters. within the same class where the
e.g method is declared.
1. public class Methodoveloading Only those methods are
2. {
overrides in the derived class
3. public int add(int a, int b)
4. //two int type Parameters method which is declared in the base
5. { class with the help of virtual
6. return a + b keyword or abstract keyword.
7. } e.g
8. public int add(int a, int b,int c) //t 1. public class Account
hree int type Parameters with same method s 2. {
ame as above 3. public virtual int balance()
9. { 4. {
10. return a + b + c; 5. return 10;
11. }
12. public float add(float a, float b,float 6. }
c,float d) //four float type Parameters w 7. }
ith same method same as above two method 8. public class Amount : Account
13. { 9. {
14. return a + b + c + d; 10.
15. } 11. public override int balance()
16. }
12. {
In the above example, there are three methods 13. return 500;
14. }
with same method same but they differ with
15. }
number of parameters and type of parameters,
hence this types of methods is called as method Output of the above Program is
overloading. 10 and 500

Part 24 - Difference b/w method overriding and hiding


Method Overriding Method Hiding
In method overriding a base class reference In method hiding a base class reference
variable pointing to a child class object, will variable pointing to a child class object, will
involve the overridden method in the Child invoke the hidden method in the base class
class
using System; using System;
public class BaseClass public class BaseClass
{ {
public virtual void Print() public void Print()
{ {
Console.WriteLine("I am BaseClass"); Console.WriteLine("I am BaseClass");
} }
} }
public class DerivedClass : BaseClass public class DerivedClass : BaseClass
{ {
public override void Print() public new void Print()
{ {
Console.WriteLine("I am DerivedClass"); Console.WriteLine("I am DerivedClass");
} }
} }
class Program class Program
{ {
public static void Main() public static void Main()
{ {
BaseClass b = new DerivedClass(); BaseClass b = new DerivedClass();
b.Print(); b.Print();
} }
} }
O/P: I am DerivedClass O/P: I am BaseClass Print Method

Part 25 - Method overloading


Function overloading and Method overloading terms are used interchangeably.
Method overloading allows a class to have multiple methods with the same name, but,
with a different signature. So in C# functions can be overloaded based on the number,
type (int, float etc.) and kind (Value, Ref or Out) of parameters.
The signature of a method consists of the name of the method and the type, kind (value,
reference, or output) and the number of it formal parameters. The signature of a method
does not include the return type and the params modifier. So, it is not possible to
overload a function, just based on the return type or parameter modifier.

Note: If you want to know about the different kinds of method parameters, please watch Part 17- Method
parameters.

Part 26 - Why Properties using System;


public class Student
{
public int ID;
Marking the class field public and exposing public string Name;
to the external world is bad, as you will not public int PassMark = 35;
have control over what gets assigned and }
class Program
returned. {
Problems with public fields: public static void Main()
1. ID should always be non-negative {
Student objStudent = new Student();
number.
objStudent.ID = -123;
2. Name cannot be set to NULL. objStudent.Name = null;
3. If Student Name is missing No objStudent.PassMark = 20;
Name should be returned. Console.WriteLine("ID - {0},
Name - {1}
4. PassMark should be read only. and PassMark - {2}", objStudent.ID,
objStudent.Name, objStudent.PassMark);
}
}
O/P: ID - -123, Name - and PassMark - 20

Getter and Setter Methods


Programming languages that does not have properties use getter and setter methods to
encapsulate and protect fields.
In this example we use the SetId(int Id) and GetID() methods to encapsulate_id class
field.
As a result, we have better control on what gets assigned and returned from the _id field.
Note: Encapsulation is one of the primary pillars of object oriented programming.
using System;
public class Student
{
private int _Id;
private string _Name;
private int _PassMark = 35;
public void SetId(int Id)
{
if (Id <= 0) { throw new Exception("Student Id should be greater than zero"); }
this._Id = Id;
}
public int GetId()
{
return _Id;
}
public void SetName(string Name)
{
if(string.IsNullOrEmpty(Name)) { throw new Exception("Name should be Null or Empty"); }
this._Name = Name;
}
public string GetName()
{
return string.IsNullOrEmpty(_Name) ? "No Name" : this._Name;
}
public int GetPassMark()
{
return _PassMark;
}
}
class Program
{
public static void Main()
{
Student objStudent = new Student();
objStudent.SetId(23); //objStudent.SetId(-23);
objStudent.SetName("testing");//objStudent.SetName(null);
Console.WriteLine("ID - {0}, Name - {1} and PassMark - {2}", objStudent.GetId(),
objStudent.GetName(),objStudent.GetPassMark());
}
}
Output: ID - 23, Name - testing and PassMark 35

Part 27 Properties
In C# to encapsulate and protect fields we use properties
1. We use get and set accessors to implement properties.
2. A property with both get and set accessor is a Read/Write property.
3. A property with only get accessor is a Read only property.
4. A property with only set accessor is a Write only property.
Note: The advantage of properties over traditional Get() and Set() methods is that, you can
access them as if they were public fields.
using System;
public class Student
{
private int _Id;
private string _Name;
private int _PassMark = 35;
public int Id
{
set
{
if (value <= 0) { throw new Exception("Student Id should be greater than zero"); }
this._Id = value;
}
get { return _Id; }
}
public string Name
{
set
{
if (string.IsNullOrEmpty(value)) { throw new Exception("Name should be Null or Empty"); }
this._Name = value;
}
get { return string.IsNullOrEmpty(_Name) ? "No Name" : _Name; }
}
public int PassMark
{
get { return _PassMark; }
}
}
class Program
{
public static void Main()
{
Student objStudent = new Student();
objStudent.Id = 23; //objStudent.Id = -23;
objStudent.Name = "testing";//objStudent.Name = null;
Console.WriteLine("ID - {0}, Name - {1} and PassMark - {2}", objStudent.Id,
objStudent.Name,objStudent.PassMark);
}
} Output: ID - 23, Name - testing and PassMark 35

Auto Implemented Properties:


If there is no additional logic in the property accessors, then we can make use of auto-
implemented properties introduced in C# 3.0.
Auto-implemented properties reduce the amount of code that we have to write.
When you use auto-implemented properties, the complier creates a private, anonymous
field that can only accessed through the propertys get and set accessors.

Part 28 Structs
Below way we will refactor the code,
using System;
public struct Customer
Just like classes, structs can have {
1. Private Fields private int _Id;
2. Public Properties private string _Name;
public int Id
3. Constructors {
4. Methods get { return this._Id; }
Object Initializer syntax, introduced in C# 3.0 set { this._Id = value; }
}
can be used to initialize either a struct or a
public string Name
class. {
get { return this._Name; }
set { this._Name = value; }
}
public Customer(int Id, string Name)
{
this._Id = Id;
this._Name = Name;
}
public void PrintDetails()
{
Console.WriteLine("ID: {0}, NAME: {1}", Id, Name);
}
}
class Program
Note: There are several differences between {
classes and structs which we will be looking public static void Main()
at in a later session {
Customer C1 = new Customer(101, "John");
C1.PrintDetails();
//Object Initializer syntax, introduced in C# 3.0
Customer C2 = new Customer();
C2.Id = 102;
C2.Name = "Mike";
C2.PrintDetails();
//Object Initializer syntax, introduced in C# 3.0
Customer C3 = new Customer { Id = 103, Name =
"Rosey"};
C3.PrintDetails();
}
}
Output:
ID: 101, NAME: John
ID: 102, NAME: Mike
ID: 103, NAME: Rosey

Part 29 - Difference between classes and structs


Structs Classes
1. A struct is a value type. 1. A class is a reference type.
2. Structs have the all feature of value 2. Classes have the all feature of
types. reference types.
3. Structs are stored on stack. 3. Classes are stored on the heap.
4. Value types hold their value in memory 4. Reference types hold a reference to an
where they are declared. object in memory.
5. Value types are destroyed immediately 5. In reference types only the reference
after the scope is lost. variable is destroyed after the scope is
lost. The object is later destroyed by
garbage collector. (Later session we will
discuss about GC feature in detail)
6. When you copy a struct into another 6. When you copy a class into another
struct, a new copy of that struct gets class, we only get a copy of the
created and modifications on one reference variable. Both the reference
struct will not affect the values variables point to the same object on
contained by the other structs the heap. So, operations on one
variable will affect the values
using System; contained by the other reference
public struct Customer
{ variable.
public int Id { get; set; } using System;
public string Name { get; set; } public class Customer
} {
class Program public int Id { get; set; }
{ public string Name { get; set; }
public static void Main() }
{ class Program
int i = 10; {
int j = 0; public static void Main()
j = i + 1; {
Console.WriteLine("Value of i: {0} and j = int i = 10;
{1}", i, j); int j = 0;
Customer C1 = new Customer(); j = i + 1;
C1.Id = 101; Console.WriteLine("value of i: {0} and j =
C1.Name = "Mark"; {1}", i, j);
Customer C2 = C1; Customer C1 = new Customer();
C2.Name = "Nancy"; C1.Id = 101;
Console.WriteLine("C1 Name: {0}, C2 Name: C1.Name = "Mark";
{1}", C1.Name, C2.Name); Customer C2 = C1;
} C2.Name = "Nancy";
} Console.WriteLine("C1 Name: {0}, C2 Name:
{1}", C1.Name, C2.Name);
Value of i: 10 and j = 11 }
C1 Name: Mark, C2 Name: Nancy }
Value of i: 10 and j = 11
C1 Name: Nancy, C2 Name: Nancy
7. Structs cant have destructors.
7. Classes can have destructions.

8. Structs cannot have explicit parameter


less constructor. 8. Classes can have explicit parameter
less constructor.

9. Struct cant inherit from another class.


But, both structs and classes can inherit
from an interface. 9.Classes can inherit from another class.
And, both structs and classes can
inherit from an interface.
Examples of structs in the .NET framework int (System.Int32), double (System.Double) etc.

Note 1: A class or a struct cannot inherit Note 2: How do you a class from being
from another struct. Struct are sealed types. inherited? Or what is the significance of
sealed keyword?
Part 30 - Interfaces
We create interfaces using interface keyword. Just like classes interfaces also contains
properties, methods, delegates or events, but only declarations and no implementations.

1. Its a compile time error to provide implementations for any interface member.

2. Interface members are public by default, and they dont allow explicit access modifiers.

3. Interfaces cannot contain fields.

4. If class or a struct inherits from an interface, it must provide implementation for all
interface members. Otherwise, we get a compiler error.
5. A class or a struct can inherit from more than one interface at the same time, but
whereas, a class cannot inherit from more than once class at the same time.

6. Interfaces can inherit from other interfaces. A class that inherits this interface must
provide implementation for all interface members in the entire interface inheritance
chain.
using System;
interface ICustomer1
{
void Print1();
}
interface ICustomer2 : ICustomer1
{
void Print2();
}
public class Customer : ICustomer2
{
public void Print2()
{
Console.WriteLine("Print 2 Method");
}
public void Print1()
{
Console.WriteLine("Print 1 Method");
}
}
class Program
{
public static void Main()
{
Customer C1 = new Customer();
C1.Print1();
C1.Print2();
}
}
O/P
Print 1 Method
Print 2 Method
7. We cannot create an instance of an interface, but an interface reference variable can
point to derived class object.
Usually, Interface is incomplete, they dont have any implementation. Thats why the C#
language doesnt allow to create instance of an interface

Interface Naming Conversion: Interface names are prefixed with Capital I

Part 31 - Explicit interfaces implementation


Question: A class inherits from 2 interfaces using System;
interface I1
and both interfaces have the same method {
name. How should the class implement the void InterfacMthd();
method for both the interface? }
interface I2
{
We are using Explicit interface void InterfacMthd();
Implementation technique to solve this }
class Program : I1, I2
problem. {
s void I1.InterfacMthd()
Note: When a class explicitly implements, an {
Console.WriteLine("Interface Method 1");
interface member, the interface member
}
can no longer be accessed thru class void I2.InterfacMthd()
reference variable, but only thru the {
interface reference variable. Console.WriteLine("Interface Method 2");
}
public static void Main()
Access modifiers are not allowed on {
explicitly implemented interface members. Program P = new Program();
//Typecast the interface for differentiate.
((I1)P).InterfacMthd();//Explicit Interface
using System; ((I2)P).InterfacMthd();
interface I1 //Another way
{ /*I1 i1 = new Program();
void InterfaceMthd(); I1 i2 = new Program();
} i1.InterfacMthd();
interface I2 i2.InterfacMthd();*/
{ }
void InterfaceMthd(); }
} O/P
class Program : I1, I2
Interface Method 1
{
Interface Method 2
public void InterfaceMthd()//Default
Implementation
{ Note: If you want to make one of the
Console.WriteLine("Interface Method 1");
}
interface method, the default, then
void I2.InterfaceMthd()//Explicit implement that method normally and the
Implementation other interface method explicitly. This makes
{
the default method to be accessible thru
Console.WriteLine("Interface Method 2");
} class instance.
public static void Main()
{
Program P = new Program();
P.InterfaceMthd();//Explicit Interface
((I2)P).InterfaceMthd();
}
}
O/P
Interface Method 1
Interface Method 2
Part 32 - Abstract classes
Abstract class is incomplete methods because they dont have implementation for all of their
members. Thats why we cant able to create instance class
Abstract class can be declared as abstract keyword.
using System; The abstract keyword is used to create
public abstract class Customer
{ abstract classes.
public abstract void Print(); An abstract class is incomplete and hence
} cannot be instantiated.
public class Program : Customer
{
public override void Print() An abstract class can only be used as base
{ class.
Console.WriteLine("Sample Testing");
}
public static void Main() An abstract class cannot be sealed.
{
Program P = new Program();
An abstract class may contain abstract
P.Print();
/* Below way to create instance for abstract class members (methods, properties, indexes and
Customer C = new Program(); events), but not mandatory.
C.Print();*/
}
} A non-abstract class derived from an
O/P abstract class must provide implementations
Sample Testing for all inherited abstract members.

If a class inherits an abstract class, there are 2 options available for that class
Option 1: Provide Implementation for all the abstract members inherited from the base abstract
class.
Option 2: If the class does not wish to provide Implementation for all the abstract members
inherited from the abstract class, then the class has to be marker as abstract.

Part 33 - Difference b/w abstract and interfaces classes

Abstract Interface
1. Abstract class can have 1. Interface cant have implementation
implementations for some of its for any of its members,
members (Methods).

2. Abstract class can have fields. 2. Interfaces cannot have fields.

3. Abstract class can inherit from another 3. An interface can inherit from another
abstract class or another interface. interface only and cannot inherit from
an abstract class
4. A class cannot inherit from multiple 4. A class can inherit from multiple
abstract class at the same time. interfaces at the same time.
5. Abstract class members can have 5. Interface members cannot have
access modifier. access modifier.

Part 34 - Problems of multiple class inheritance


Prerequisite: Please do watch below session using System;
class A
before processed {
Inheritance (Part 21) public virtual void Print()
Polymorphism (Part 23) { Console.WriteLine("Class A Called");}
}
Difference between method class B : A
overriding and hiding (Part 24) {
public override void Print()
CLASS A {Console.WriteLine("Class B Called");}
}
class C : A
{
public override void Print()
{Console.WriteLine("Class C Called");}
CLASS B CLASS C }
//C# doesn't suuport multiple inheritance. Lets
assume its support.
class D : B, C
{ }
public class Program
CLASS D {
public static void Main()
{
D d = new D();
D.Print();//which class does it inherit:B,or C?
} //This ambiguity is called as Diamond problem
}

1. Class A and Class C inherit from Class A.


2. Class D inherits from both B and C.
3. If a method in D calls a method defined in A (and does not override the method), B and
C have overridden that method differently, and then from which class does it inherit: B, or
C?
This ambiguity is called as Diamond problem.
Part 35 - Multiple class inheritance using interfaces
using System; class AB: IA, IB
interface IA {
{ A a = new A();
void AMethod(); B b = new B();
}
class A : IA public void AMethod()
{ {
public void AMethod() a.AMethod();
{ }
Console.WriteLine("CA IA"); public void BMethod()
} {
} b.BMethod();
interface IB }
{ }
void BMethod(); public class Program
} {
class B : IB public static void Main()
{ {
public void BMethod() AB ab = new AB();
{ ab.AMethod();
Console.WriteLine("CB IB"); ab.BMethod();
} }
} } O/P: CA IA CB IB

Part 36 - Delegates
A delegate is a type safe function pointer. That is, it holds a reference (Pointer) to a function.

The signature of the delegate must match the signature of the function, the delegate points to,
otherwise you get a complier error. This is the reason delegates are called as type safe function
pointers.

A Delegate is similar to a class. You can create an instance of it, and when you do so, you pass
in the function name as a parameter to the delegate constructor, and it is to this function the
delegate will point to.
using System;
public delegate void HelloFunctionDelegate(string Message);
public class Program
{
public static void Hello(string strMessage)
{
Console.WriteLine(strMessage);
}
public static void Main()
{ //A Delegate is a type safe function pointer
HelloFunctionDelegate del = new HelloFunctionDelegate(Hello);
del("Hello Delegate Mthd");
}
}
O/P: Hello Delegate Mthd
Tip to remember delegate syntax: Delegates syntax look very much similar to a method with the
delegate keyword.
Part 37 - Delegates usage
using System;
using System.Collections.Generic;
class Employee
{
public int ID { get; set; }
public string Name { get; set; }
public int Salary { get; set; }
public int Experience { get; set; }
public static void PromotedEmployee(List<Employee> EmployeeList)
{
foreach(Employee emp in EmployeeList)
{
if (emp.Experience >= 5) Console.WriteLine(emp.Name + " " + "Promoted");
}
}
}
public class Program
{
public static void Main()
{
List<Employee> e = new List<Employee>();
e.Add(new Employee { ID = 101, Name = "Mark", Salary = 2000, Experience = 5 });
e.Add(new Employee { ID = 102, Name = "Nike", Salary = 4000, Experience = 4 });
e.Add(new Employee { ID = 103, Name = "Rose", Salary = 3000, Experience = 3 });
e.Add(new Employee { ID = 104, Name = "Nancy", Salary = 6000, Experience = 6 });
e.Add(new Employee { ID = 105, Name = "Mary", Salary = 7000, Experience = 7 });
Employee.PromotedEmployee(e);
}
}O/P:Mark Promoted
Nancy Promoted
Mary Promoted

Part 38 - Delegates usage continued


using System;
using System.Collections.Generic;
delegate bool IsPromoted(Employee em);
class Employee
{
public int ID { get; set; }
public string Name { get; set; }
public int Experience { get; set; }
public int Salary { get; set; }
public static void PromotedEmployee(List<Employee> Emp, IsPromoted IsEligibilepromo)
{
foreach (Employee eItem in Emp) if (IsEligibilepromo(eItem))Console.WriteLine(eItem.Name + "Promoted");
}
}
class Program
{
public static bool EmployeePromotion(Employee Emp)
{
return Emp.Experience >= 5 ? true : false;
}
public static void Main()
{
List<Employee> e = new List<Employee>();
e.Add(new Employee { ID = 101, Name = "Jessy", Experience = 2, Salary = 2000 });
e.Add(new Employee { ID = 102, Name = "Romeo", Experience = 3, Salary = 3000 });
e.Add(new Employee { ID = 103, Name = "John", Experience = 5, Salary = 5000 });
e.Add(new Employee { ID = 104, Name = "Martin", Experience = 9, Salary = 9000 });
e.Add(new Employee { ID = 105, Name = "Rushi", Experience = 8, Salary = 8000 });
e.Add(new Employee { ID = 106, Name = "Stephenie", Experience = 6, Salary = 6000 });
IsPromoted isPromoted = new IsPromoted(EmployeePromotion);
Employee.PromotedEmployee(e, isPromoted);
}
}
O/P:
John Promoted
Martin Promoted
Rushi Promoted
Stephenie Promote
Update few lines using Lambda Expression,
using System;
using System.Collections.Generic;
delegate bool IsPromoted(Employee em);
class Employee
{
public int ID { get; set; }
public string Name { get; set; }
public int Experience { get; set; }
public int Salary { get; set; }
public static void PromotedEmployee(List<Employee> Emp, IsPromoted IsEligibilepromo)
{
foreach (Employee eItem in Emp)
{
if (IsEligibilepromo(eItem)) Console.WriteLine(eItem.Name + " Promoted");
}
}
}
class Program
{
public static void Main()
{
List<Employee> e = new List<Employee>();
e.Add(new Employee { ID = 101, Name = "Jessy", Experience = 2, Salary = 2000 });
e.Add(new Employee { ID = 102, Name = "Romeo", Experience = 3, Salary = 3000 });
e.Add(new Employee { ID = 103, Name = "John", Experience = 5, Salary = 5000 });
e.Add(new Employee { ID = 104, Name = "Martin", Experience = 9, Salary = 9000 });
e.Add(new Employee { ID = 105, Name = "Rushi", Experience = 8, Salary = 8000 });
e.Add(new Employee { ID = 106, Name = "Stephenie", Experience = 6, Salary = 6000 });
Employee.PromotedEmployee(e, emp => emp.Experience >= 5);
}
}
O/P:
Mark Promoted
Nancy Promoted
Mary Promoted

Part 39 - Multicast Delegates


A Multicast delegate is a delegate that has reference to more than one function. When you
invoke a multicast delegate, all the functions the delegate is pointing to, are invoked.
There are 2 approaches to create a multicast delegate. Depending on the approach you use
+ or += to register a method with the delegate
- or -= to un-register a method with the delegate

Note: A multicast delegate invokes the methods in the invocation list, in the same order in which
they are added.
If the delegate has a return type other than void and if the delegate is a multicast delegate,
only the value of the last invoked method will be returned. Along the same lines, if the delegate
has an out parameter, the value of the output parameter, will be the value assigned by the last
method.
Common interview question Where do you use multicast delegates?
Multicast delegate makes implementation of observer design pattern very simple. Observer
pattern is also called as publish/subscribe pattern.
using System;
public delegate void MDeleg(); using System;
class Program public delegate void MDeleg();
{ class Program
public static void Main() {
{ public static void Main()
MDeleg Q1, Q2, Q3, Q4; {
Q1 = new MDeleg(SelectedOne); MDeleg Q1 = new MDeleg(SelectedOne);
Q2 = new MDeleg(SelectedTwo); Q1 += SelectedTwo;
Q3 = new MDeleg(SelectedThree); Q1 += SelectedThree;
Q4 = Q1 + Q2 + Q3 - Q1; Q1 -= SelectedTwo;
Q4(); Q1();
} }
public static void SelectedOne() public static void SelectedOne()
{ {
Console.WriteLine("SelectedOne Called"); Console.WriteLine("SelectedOne Called");
} }
public static void SelectedTwo() public static void SelectedTwo()
{ {
Console.WriteLine("SelectedTwo Called"); Console.WriteLine("SelectedTwo Called");
} }
public static void SelectedThree() public static void SelectedThree()
{ {
Console.WriteLine("SelectedThree Called"); Console.WriteLine("SelectedThree Called");
} }
} }
O/P: O/P:
SelectedTwo Called SelectedOne Called
SelectedThree Called SelectedThree Called
Used input and Output parameter
using System;
using System; public delegate void MDeleg(out int Value);
public delegate int MDeleg(); class Program
class Program {
{ public static void Main()
public static void Main() {
{ MDeleg Q1 = new MDeleg(SelectedOne);
MDeleg Q1 = new MDeleg(SelectedOne); Q1 += SelectedTwo;
Q1 += SelectedTwo; Q1 -= SelectedThree;
Q1 += SelectedThree; int OutputreturnVal = -1;
int returnVal = Q1(); Q1(out OutputreturnVal);
Console.WriteLine("RV: {0}", returnVal); Console.WriteLine("OutVal: {0}",
} OutputreturnVal);
public static int SelectedOne() }
{ public static void SelectedOne(out int Value)
return 1; {
} Value = 1;
public static int SelectedTwo() }
{ public static void SelectedTwo(out int Value)
return 2; {
} Value = 2;
public static int SelectedThree() }
{ public static void SelectedThree(out int Value)
return 3; {
} Value = 3;
} }
O/P: }O/P:
RV: 3. . . OutVal: 2

Part 40 - Exception Handling


An exception is an unforeseen error that occurs when a program is running.
Examples:
Trying to read from a file that does not exist, throws FileNotFoundException.
Trying to read from a database table that does not exist, throws a SqlException.

Showing actual unhandled exceptions to the end user is bad for two reasons
1. Users will be annoyed as they are cryptic and does not make sense to the end users.
2. Exceptions contain information, which can be used for hacking into your application.

An exception is actually a class that derives from System.Exception class. The System.Exception
class has several useful properties, which provide valuable information about the exception.
Message: Gets a message that describes the current exception.
Stack Trace: Provides the call stack to the line number in the method where the exception
occurred.
using System;
using System.IO;
class ExceptionHandle
{
public static void Main()
{
StreamReader strReader = null;
try
{ //@ - Verbatim String Literal. It means that escaping isn't applied.
strReader = new StreamReader(@"C:\Users\sathys\Desktop\sa.txt");
Console.WriteLine(strReader.ReadToEnd());
}
catch(FileNotFoundException exFile)
{
Console.WriteLine("File '{0}' is not found", exFile.FileName);
}
catch(Exception ex) //Exception should be always @ last or else will get compiler error
{
Console.WriteLine(ex.Message);
}
/* though the 'finally' is optional but if we are not use it. Incase if
we get any exception in 'catch' that time the strReader shouldn't close*/
finally
{
if (strReader != null) strReader.Close();
}
}
}
O/P:<<<if we pass correct filename then the result should be read the text from the file>>>
Could not find a part of the path 'C:\Users\sathys\Desktop\sa.txt'.
Releasing System Resources
We use try, catch and finally blocks for exception handling.
try The codes that can possible cause an exception will be in the try block.
catch Handles the exception.
finally Clean and free resources that the class was holding onto during the program execution.
Finally block is optional.

Note: It is a good practice to always release resources in the finally block, because finally block
is guaranteed to execute, irrespective of whether there is an exception or not.

Specific exceptions will be caught before the base general exception, so specific exception
blocks should always be on top of the base exception block. Otherwise, you will encounter a
complier error.

Part 41 - Inner Exceptions


The InnerException property returns the Exception instance that caused the current exception.
To retain the original exception pass it as a parameter to the constructor, of the current
exception.
Always check if inner exception is not null before accessing any property of the inner exception
object, else, you may get Null Reference Exception.
To get the type of InnerException use GetType() method.
using System;
using System.IO;
class InnerExceptionHandle
{
public static void Main()
{
try
{
try
{
Console.WriteLine("Enter the First & Second Number");
int FN = Convert.ToInt16(Console.ReadLine());
int LN = Convert.ToInt16(Console.ReadLine());
int Result = FN / LN;
Console.WriteLine("Result: {0}", Result);
}
catch(Exception ex)
{
string fileName = @"C:\Users\sathy\Desktop\StudyMaterial\slogs.txt";
if (File.Exists(fileName))
{
StreamWriter strWriter = new StreamWriter(fileName);
strWriter.Close();
Console.WriteLine("Invalid format: {0}", ex.GetType().Name);
}
else
{
throw new FileNotFoundException("File is not found : " + fileName, ex);
}
}
}
catch(Exception exc)
{
Console.WriteLine("Current Exception: {0}", exc.GetType().Name);
Console.WriteLine("Inner Exception: {0}", exc.InnerException.GetType().Name);
}
}
}
O/P:
Enter the First & Second Number
50
0
Current Exception: FileNotFoundException
Inner Exception: DivideByZeroExceptionss any key to continue . . .

Part 42 - Custom Exceptions


To understand custom exceptions, you should have good understanding of
Pat 21 Inheritance
Pat 40 Exception Handling Basics
Pat 41 Inner Exception
When do you usually go for creating your own custom exception?
If none of the already existing .Net exception adequately describes the problem.
Example
1. I have an asp.net web application.
2. The application should allow the user to have only one logged in session.
3. If the user is already logged in, and if he opens another browser window and tries to login
again, the application should throw an error stating he is already logged in another
browser window.
Within the .NET framework we dont have any exception that adequately describes this
problem. So this scenario is one of the examples where you want to create a custom exception.
using System;
using System.IO;
using System.Runtime.Serialization;
class CustomExceptionHandle
{
public static void Main()
{
try
{
throw new UserLoginHandleException("User already logged in, no duplicate session allowed");
}
catch(UserLoginHandleException ex)
{
Console.WriteLine(ex.Message);
}
}
}
[Serializable]
class UserLoginHandleException : Exception
{
public UserLoginHandleException() : base(){}
public UserLoginHandleException(string strMessage):base(strMessage){}
public UserLoginHandleException(string strMessage, Exception innerEx) : base(strMessage, innerEx){}
public UserLoginHandleException(SerializationInfo serInfo, StreamingContext serContext) :
base(serInfo, serContext){}
}O/P:
User already logged in, no duplicate session allowed . . .
CUSTOM EXCEPTION - STEPS
1. Create a class that derives from Systern.Exption class. As a convention, end the class
name with Exception suffix. All .NET exceptions end with, exception suffix.
2. Provide a public constructor that takes n a string parameter. This constructor simply
passes the string parameter, to the base exception class constructor.
3. Using lnnerExceptions, you can also track back the original exception. If you want to
provide this capability for your custom exception class, then overload the constructor
accordingly.
4. If you want your Exception class object to work across application domains, then the
object must be serializable. To make your exception class serializable mark it with
serializable attribute and provide a constructor that invokes the base Exception class
constructor that takes in SerializationInfo and StreamiigContext objects as parameters.

Note: It is also possible to provide your own custom serialization, which will discuss In a later
session.

Part 43 - Exception handling abuse


Exceptions are unforeseen errors that occur when a program is running. For example, when an
application is executing a query, the database connection is lost. Exception handling is
generally used to handle these scenarios.
Using exception handling to implement program logical flow is bad and is termed as exception
handling abuse.
using System;
class ExceHandle
{
public static void Main()
{
try
{
Console.WriteLine("Please enter Numerator:");
int FN = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Please enter Denominator:");
int SN = Convert.ToInt32(Console.ReadLine());
int Result = FN / SN;
Console.WriteLine("The Result is: {0}", Result);
}
catch(FormatException)
{Console.WriteLine("Please use the Number format");}
catch(OverflowException)
{Console.WriteLine("Use the num b/n {0} to {1}", Int32.MinValue, Int32.MaxValue);}
catch(DivideByZeroException)
{Console.WriteLine("The denominator shouldn't be Zero");}
catch(Exception ex)
{Console.WriteLine("Generic Error: {0}", ex.Message);}
}
}
O/P: Please enter Numerator:
45
Please enter Denominator:
0
The denominator shouldn't be Zero.

Part 44 - Preventing exception handling abuse


using System;
class ExceHandle
{
public static void Main()
{
int Numerator;
Console.WriteLine("Enter the Numerator");
bool IsNumeratorConversionSuccessful = Int32.TryParse(Console.ReadLine(), out Numerator);
if (IsNumeratorConversionSuccessful)
{
int Denominator;
Console.WriteLine("Enter the Denominator");
bool IsDenominatorConversionSuccessful = Int32.TryParse(Console.ReadLine(), out
Denominator);
if (IsDenominatorConversionSuccessful && Denominator != 0)
{
int Result = Numerator / Denominator;
Console.WriteLine("The Result: {0}", Result);
}
else
{
if (Denominator == 0) Console.WriteLine("The denominator shouldn't be Zero"); else
Console.WriteLine("Please enter the num between {0} to {1}", Int32.MinValue, Int32.MaxValue);
}
}
else
{
Console.WriteLine("Please enter the num between {0} to {1}", Int32.MinValue,
Int32.MaxValue);
}
}
}O/P: Enter the Numerator
44
Enter the Denominator
0
The denominator shouldn't be Zero
Part 45 - Why Enums
Part 46 - Enums Example
Enums are strongly typed constants.

If a program uses set of integral numbers, consider replacing them with enums. Otherwise the
program becomes less
Readable
Maintainable

In the next session we will replace, these integral numbers with enums, which makes the program
better readable and maintainable.
using System;
class Program
{
public static void Main()
using System; {
class Program Customer[] cus = new Customer[3];
{ cus[0]=new Customer{Name="Mark",Gender=Gender.Male};
public static void Main() cus[1]=new Customer{Name="Mary",Gender=Gender.Female};
{ cus[2]=new Customer{Name="Jessy",Gender=Gender.Unknown};
Customer[] cus = new Customer[3]; foreach (Customer cs in cus)
cus[0] = new Customer {Name="Mark",Gender=0}; {
cus[1] = new Customer {Name="Mary",Gender=1}; Console.WriteLine("Name: {0}, Gender: {1}",
cus[2] = new Customer {Name="Jessy",Gender=2}; cs.Name, getGender(cs.Gender));
foreach (Customer cs in cus) }
{ }
Console.WriteLine("Name: {0}, Gender: {1}", public static string getGender(Gender gender)
cs.Name, getGender(cs.Gender)); { //0 - Male, 1 - Female, 2 - Unknown
} switch (gender)
} {
public static string getGender(int intGender) case Gender.Male: return "Male";
{ //0 - Male, 1 - Female, 2 - case Gender.Female: return "Female";
Unknown case Gender.Unknown: return "Unknown";
switch (intGender) default: return "Not Declare";
{ }
case 0: return "Male"; }
case 1: return "Female"; }
case 2: return "Unknown"; public enum Gender
default: return "Not Declare"; {
} Male,
} Female,
} Unknown
class Customer }
{ class Customer
public string Name { get; set; } {
public int Gender { get; set; } public string Name { get; set; }
} public Gender Gender { get; set; }
O/P: Name: Mark, Gender: Male }O/P: Name: Mark, Gender: Male
Name: Mary, Gender: Female Name: Mary, Gender: Female
Name: Jessy, Gender: Unknown Name: Jessy, Gender: Unknown

Part 47 Enums
In a program uses set of integral numbers, consider replacing them with enums, which makes
the program more
Readable
Maintainable
1. Enums are enumerations.
2. Enums are strongly typed constants. Hence, an explicit cast is needed to convert from enum
type to an integral type and vice versa. Also, an enum of one type cannot be implicitly
assigned to an enum of another type even though the underlying values of their members
are the same.

3. The default underlying type of an enum is int.


4. The default value for first element is ZERO and gets incremented by 1.
5. It is possible to customize the underlying type and values.

6. Enums are value types.


7. enum keyword (all small letters) is used to create enumerations, whereas Enum class,
contains static GetValues() and GetNames() methods which can be used to list Enum
underlying type values and Names.
using System;
public enum Gender : short
{
Male,Female,Unknown
}
class Program
{
public static void Main()
{
short[] Values =
(short[])(Enum.GetValues(typeof(Gender)));
foreach(short val in Values)
{
Console.WriteLine(val);
}
string[] Names = Enum.GetNames(typeof(Gender));
foreach(string gen in Names)
{
Console.WriteLine(gen);
}
}
}O/P: 0
1
2
Male
Female
Unknown

Part 48 - Difference between Types and Type Members


using System;
class Customer
{
#region Fields
private int _id;
private string _firstName;
private string _lastName;
#endregion

#region Properties
public int ID { get { return _id; } set { _id = value; } }
public string FirstName { get { return _firstName; } set { _firstName = value; } }
public string LastName { get { return _lastName; } set { _lastName = value; } }
#endregion

#region Method
public string GetFullName()
{
return this.FirstName + " - " + this.LastName;
}
#endregion
}
In c# there are 5 different access modifiers:
1. Private
2. Protected
3. Internal
4. Protected Internal
5. Public
Note: Using regions you can expand and collapse sections of your code either manually, or
using visual studio Edit Outlining Toggle All Outlining
TYPE TYPE MEMBERS
1. In this example - Customer in the Type 1. In this example - Fields, Properties and
Method are Type Members
2. In general classes, struct, enum, 2. Fields, properties, constructors,
interfaces and delegates are called as methods, etc., that normally reside in a
Type type are called as type members.
3. Types can have only 2 (internal, public) 3. Type Members can have all the access
of the 5 access modifiers modifiers
4. Default access modifier - internal 4. Default access modifier - private

Part 49 - Access Modifiers Private, Public & Protected

Private members are available only with in


the containing type, whereas public
members are available anywhere. There is
no restriction.

Protected Members are available, with in


the containing type and to the types that
derived from the containing type.

Access Modifier Accessibility


Private Only within the containing class. (Default for Type Members)
Private members are accessible only within the body of the class or the
struct in which they are declared
Public Anywhere, No Restrictions
Public access is the most permissive access level. There are no restrictions
on accessing public members
Protected Within the containing types and types derived from the containing type
A protected member is accessible within its class and by derived class
instances.
Internal Anywhere within the containing assembly.
Internal types or members are accessible only within files in the same
assembly
Protected Internal Anywhere within the containing assembly, and from within a derived class
in any another assembly. (Default for Types)

Part 50 - Access Modifiers Internal and Protected Internal


A member with internal access modifier is available anywhere within the containing assembly.
Its a compile time error to access, an internal member from outside the containing assembly.

Protected Internal members can be accessed by any code in the assembly in which it is
declared, or from within a derived class in another assembly. It is a combination of protected
and internal. If you have understood protected and internal, this should be very easy to follow.
Part 51 - Access Modifiers for types
You can use all the 5 access modifiers with type members, but a types allows only internal and
public access modifiers. It is a compile time error to use private, protected and protected
internal access modifiers with types.

Part 52 - Attributes
Attributes allow you to add declarative information to your programs. This information can then
be queried at runtime using reflection.

There are several Pre-defined Attributes provided by .NET. It is also possible to create your own
Custom Attributes.

I am waiting for updates. Please share me if you get any response from the customer.

A few pre -defined attributes with in the .NET framework:


Obsolete - Marks types and type members outdated.
WebMethod - To expose a method as an XML Web service method
Serializable - Indicates that a class can be serialized

It is possible to customize the attribute using parameters

An attribute is a class that inherits from System.Attribute base class.


Note: Obsolete is referred to the class ObsoleteAttribute. But Attribute is optional we can directly
use Obsolete

using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
int Sum = Calculator.Add(new List<int> { 5, 6 });
Console.WriteLine(Sum);
int Sum1 = Calculator.Add(5, 6); //Warning CS0618 'Calculator.Add(int, int)' is obsolete: 'Use [
Add(List<int> numbers) ] Method'
}
}
public class Calculator
{
//Obsolete is referred to the class 'ObsoleteAttribute'.But Attribute is optional we can directly use Obsolete
[Obsolete("Use [ Add(List<int> numbers) ] Method") ]
public static int Add(int FN, int SN)
{
return FN + SN;
}
public static int Add(List<int> numbers)
{
int sum = 0;
foreach (int Number in numbers) { sum = sum + Number; }
return sum;
}
} O/P: 11

Part 53 - Reflection
Reflection is the ability of inspecting an assemblies metadata at runtime. It is used to find all
types in an assembly and/or dynamically invoke methods in an assembly.
Uses of reflection:
1. When you drag and drop a button on a win forms or an asp.net application. The
properties window uses reflection to show all the properties of the Button class. So,
reflection extensively used by IDE or a UI designers.
2. Late binding can be achieved by using reflection. You can use reflection to dynamically
create an instance of a type, about which we dont have any information at compile
time. So, reflection enables you to use code that is not available at compile time.
3. Consider an example where we have two alternate implementations of an interface.
You want to allow the user to pick one or the other using a config file. With reflection, you
can simply read the name of the class whose implementation you want to use from the
config file, and instantiate an instance of that class. This is another example for late
binding using reflection.
using System;
using System.Reflection;
namespace Program
{
public class MainClass
{
public static void Main()
{ //3 ways we will get type of 'Customer'
Type T = Type.GetType("Program.Customer");//WAY 1
//Type T = typeof(Customer); //WAY 2
//Customer C1 = new Customer(); //WAY 3
//Type T = C1.GetType();
Console.WriteLine(T.FullName);
Console.WriteLine();//Get Property List
Console.WriteLine("Get the properties list in the Program");
PropertyInfo[] properties = T.GetProperties();
foreach (PropertyInfo property in properties) { Console.WriteLine(property.PropertyType.Name +
" - " + property.Name); }
Console.WriteLine();//Get Method List
Console.WriteLine("Get the Methods list in the Program");
MethodInfo[] methods = T.GetMethods();
foreach (MethodInfo method in methods) { Console.WriteLine(method.ReturnType + " - " +
method.Name); }
Console.WriteLine();//Get Constructor List
Console.WriteLine("Get the Constructors list in the Program");
ConstructorInfo[] constructors = T.GetConstructors();
foreach (ConstructorInfo constructor in constructors) {
Console.WriteLine(constructor.ToString() + " - " + constructor.Name); }

}
}
public class Customer
{
public int ID { get; set; }
public string Name { get; set; }
public Customer() { this.ID = -1; this.Name = string.Empty; }
public Customer(int _id, string _name) { this.ID = _id; this.Name = _name; }
public void PrintMtd()
{
Console.WriteLine("Name: {0}", this.Name);
}
}
}
O/P: Program.Customer

Get the properties list in the Program


Int32 - ID
String - Name

Get the Methods list in the Program


System.Int32 - get_ID
System.Void - set_ID
System.String - get_Name
System.Void - set_Name
System.Void - PrintMtd
System.String - ToString
System.Boolean - Equals
System.Int32 - GetHashCode
System.Type - GetType

Get the Constructors list in the Program


Void .ctor() - .ctor
Void .ctor(Int32, System.String) - .ctor
Void .ctor() - .ctor
Void .ctor(Int32, System.String) - .ctor
Part 54 - Reflection Example
using System;
using System.Reflection;
using System.Windows.Forms;
namespace ReflectionDemo
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
lstProperties.Items.Clear();
lstMethods.Items.Clear();
lstConstructors.Items.Clear();
string strTypeName = txtTypeName.Text;
Type T = Type.GetType(strTypeName);
PropertyInfo[] properties = T.GetProperties();
foreach (PropertyInfo property in properties) lstProperties.Items.Add(property.Name + " " +
property.PropertyType.Name);
MethodInfo[] methods = T.GetMethods();
foreach (MethodInfo method in methods) lstMethods.Items.Add(method.Name + " " +
method.ReturnType.Name);
ConstructorInfo[] constructors = T.GetConstructors();
foreach (ConstructorInfo contructor in constructors)
lstConstructors.Items.Add(contructor.ToString() + " " + contructor.Name);
}
}
}

Part 55 Difference b/w Late and Early Binding using reflection


Use Late Binding only when working with an objects that are not available at compile time.
Early Binding Late Binding
Early Binding can flag errors at compile-time Late binding there is a risk of run-time exceptions
Early Binding is much better for performance Late Binding is less performance than Early Binding
than Late Binding
using System; using System;
public class Program using System.Reflection;
{ public class Program
public static void Main() {
{ public static void Main()
Customer C1 = new Customer(); {
string FullName = C1.PrintMtd("Raman", Assembly AE = Assembly.GetExecutingAssembly();
"Seetha"); Type T = AE.GetType("Customer");
Console.WriteLine(FullName); object CI = Activator.CreateInstance(T);
} MethodInfo MN = T.GetMethod("PrintMtd");
} string[] param = new string[2];
public class Customer param[0] = "Raman";
{ param[1] = "Seetha";
public string PrintMtd(string strFN, string string FullName = (string)MN.Invoke(CI, param);
strLN) Console.WriteLine(FullName);
{ }
return "Name: " + strFN + " " + strLN; }
} public class Customer
}O/P: Name: Raman Seetha {
public string PrintMtd(string strFN, string strLN)
{
return "Name: " + strFN + " " + strLN;
}
}O/P: Name: Raman Seetha

Part 56 Generics
Generics are introduced in C# 2.0. Generics allow us to design classes and methods decoupled
from the data types. Generic classes are extensively used by collection classes available in
System.Collections.Generic namespace. (Covered in the next session)

One way of making AreEqual() method reusable, is to use object type parameters. Since, every
type in .NET directly or indirectly inherit from System.Object type, AreEqual() method works with
any data type, but the problem is performance degradation due to boxing and unboxing
happening.

Also, AreEqual() method is no longer type safe. It is now possible to pass integer for the first
parameter, and a string for the second parameter. It doesn't really make sense to compare
strings with integers.

So, the problem with using System.Object type is that


1. AreEqual() method is not type safe
2. Performance degradation due to boxing and unboxing.
using System; using System;
public class Program public class Program
{ {
public static void Main() public static void Main()
{ {
bool Result=Calculator.AreEqual<int>(12,12); bool Result=Calculator<int>.AreEqual(12,12);
if (Result) Console.WriteLine("Is Equal"); if (Result) Console.WriteLine("Is Equal");
else Console.WriteLine("Is Not Equal"); else Console.WriteLine("Is Not Equal");
} }
} }
public class Calculator public class Calculator<T>
{ {
public static bool AreEqual<T>(T Num1, T Num2) public static bool AreEqual(T Num1, T Num2)
{ {
return Num1.Equals(Num2); return Num1.Equals(Num2);
} }
}O/P: Is Equal }O/P: Is Equal
To make AreEqual() method generic, we specify a type parameter using angular brackets as
shown below. public static bool AreEqual<T>(T value1, T value2)

At the point, when the client aide wants to invoke this method, they need to specify the type;
they want the method to operate on. If the user wants the AreEqual() method to work with
integers, they can invoke the method specifying int as the datatype using angular brackets as
shown below. bool Equal = CaIculator.AreEqual<int>(2, 1);

To operate with string data type bool Equal = CaIculator.AreEqual<string>(A, B);

In this example, we made the method generic. Along the same lines, it is also possible to make
classes, interfaces and delegates generic.

Part 57 - Why should you override ToString Method


Before Override ToString After Override ToString
using System; using System;
namespace Program namespace Program
{ {
public class MainClass public class MainClass
{ {
public static void Main() public static void Main()
{ {
Customer C1 = new Customer(); Customer C1 = new Customer();
C1.strFirstName = "Ted"; C1.strFirstName = "Ted";
C1.strLastName = "Mosby"; C1.strLastName = "Mosby";
Console.WriteLine(C1.ToString()); //Console.WriteLine(Convert.ToString(C1));
} Console.WriteLine(C1.ToString());
} }
public class Customer }
{ public class Customer
public string strFirstName { get; set; } {
public string strLastName { get; set; } public string strFirstName { get; set; }
} public string strLastName { get; set; }
}O/P: Program.Customer public override string ToString()
{
return strFirstName+", "+strLastName;
}
}
}O/P: Ted, Mosby

Part 58 - Why should you override Equals Method


using System; using System;
using System; namespace Program namespace Program
namespace Program { {public class MainClass
{ public class MainClass {public static void Main()
public class MainClass { {Customer C1 = new Customer();
{ public static void Main() C1.FName = "Tom";
public static void Main() { C1.FName = "Jerry";
{ Direction D1 = Direction.East; Customer C2 = C1;
int i = 10; Direction D2 = Direction.East; Console.WriteLine(C1 == C2);
int j = 10; Console.WriteLine(D1 == D2); Console.WriteLine(C1.Equals(C2));
Console.WriteLine(i == j); Console.WriteLine(D1.Equals(D2)); }
Console.WriteLine(i.Equals(j)); } }
} } public class Customer
} public enum Direction { East, West, {public string FName;
}O/P: True True North, South } public string LName;
}O/P: True True }}O/P: True True
Without Equal Override With Equal Override
using System; using System;
namespace Program namespace Program
{ {
public class MainClass public class MainClass
{ {
public static void Main() public static void Main()
{ {
Customer C1 = new Customer(); Customer C1 = new Customer();
C1.FName = "Tom"; C1.FName = "Tom";
C1.FName = "Jerry"; C1.FName = "Jerry";
Customer C2 = new Customer(); Customer C2 = new Customer();
C2.FName = "Tom"; C2.FName = "Tom";
C2.FName = "Jerry"; C2.FName = "Jerry";
Console.WriteLine(C1 == C2); Console.WriteLine(C1 == C2);
Console.WriteLine(C1.Equals(C2)); Console.WriteLine(C1.Equals(C2));
} }
} }
public class Customer public class Customer
{ {
public string FName; public string FName { get; set; }
public string LName; public string LName { get; set; }
} public override bool Equals(object obj)
}O/P: False False {
Both the Reference and Value equality if (obj == null) return false;
returns false, which doesnt make sense. if (!(obj is Customer)) return false;
return this.FName == ((Customer)obj).FName &&
this.LName == ((Customer)obj).LName;
Reference Equality - should false }
because both have 2 different object public override int GetHashCode()
Value Equality - should true because {
both FName & LName values for both return this.FName.GetHashCode() ^ this.LName.GetHashCode();
object are same. }
}
}O/P: False True
Thats why we go for Override

Part 59 - Difference between Convert.ToString and ToString


Depending on the type of the application, architecture and what you are trying to achieve, you
choose one over the other
Convert.ToString() ToString()
Convert.ToString() handles null. ToString() doesn't handle null, and throws a
NULL Reference exception.
using System; using System;
namespace Program namespace Program
{ {
public class MainClass public class MainClass
{ {
public static void Main() public static void Main()
{ {
Customer C1 = new Customer(); Customer C1 = new Customer();
Console.WriteLine(C1.ToString()); Console.WriteLine(Convert.ToString(C1));
} }
} }
public class Customer public class Customer
{ {
public string Name { get; set; } public string Name { get; set; }
} }
}O/P: Program.Customer }O/P: Program.Customer
using System; using System;
namespace Program namespace Program
{ {
public class MainClass public class MainClass
{ {
public static void Main() public static void Main()
{ {
Customer C1 = null; Customer C1 = null;
Console.WriteLine(C1.ToString()); Console.WriteLine(Convert.ToString(C1));
} }
} }
public class Customer public class Customer
{ {
public string Name { get; set; } public string Name { get; set; }
} }
} }

Part 60 - Difference between String and StringBuilder


As StringBuilder objects are mutable, they offer better performance than string objects of type
System.String, when heavy string manipulation is involved
String StringBuilder
System.String is immutable StringBuilder is Mutable

Present in the namespace - using System; Present in the namespace - using System.Text;
string s = string.Empty; StringBuilder sb = new StringBuilder();
for (i = 0; i < 1000; i++) { for (i = 0; i < 1000; i++) {
s += i.ToString() + " "; sb.Append(i);
} sb.Append(' ');}
You'll end up creating 2001 strings here, This should place much less stress on the memory
2000 of which are thrown away. allocator.
using System; using System;
namespace Program using System.Text;
{ namespace Program
public class MainClass {
{ public class MainClass
public static void Main() {
{ public static void Main()
string userString = "C#"; {
userString += " Videos"; StringBuilder userString = new StringBuilder("C#");
userString += " Tutorial"; userString.Append(" Videos");
userString += " for"; userString.Append(" Tutorial");
userString += " beginners"; userString.Append(" for");
Console.WriteLine(userString); userString.Append(" beginners");
} Console.WriteLine(userString);
} }
}O/P: C# Videos Tutorial for beginners }
}O/P: C# Videos Tutorial for beginners
Part 61 - Partial classes
Partial classes allow us to split a class into 2 or more files. All these parts are then combined into a
single class, when the application is compiled. The partial keyword can also be used to split a
struct or an interface over two or more files.
Advantages of partial classes
1. The main advantage is that, visual studio uses partial classes to separate, automatically
generated system code from the developer1s code. For example, when you add a
webform, two .CS files are generated
a) WebForm1.aspx.cs- Contains the developer code
b) WebForm1.aspx.designer.cs- Contains the system generated code. For example,
declarations for the controls that you drag and drop on the webform.
2. When working on large projects, spreading a class over separate files allows multiple
programmers to work on t simultaneously. Though, Microsoft claims this as an
advantage, I havent really seen anywhere, people using partial classes, just to work on
them simultaneously.

Next Session: Rules to keep in mind when creating partial classes


Below is the sample example for the partial class
Customer.cs PartialClassOne.cs
namespace WebApplication namespace WebApplication
{ {
public class Customer public partial class CusPartialClass
{ {
private string _fname; private string _fname;
private string _lname; private string _lname;
public string FName { get { return _fname; } public string FName { get { return _fname; }
set { _fname = value; } } set { _fname = value; } }
public string LName { get { return _lname; } public string LName { get { return _lname; }
set { _lname = value; } } set { _lname = value; } }
public string GetFullName() }
{ }
return _fname + ", " + _lname; PartialClassTwo.cs
} namespace WebApplication
} {
} public partial class CusPartialClass
CusPartialClass is the partial class used {
among both PartialClassOne and public string GetFullName()
{
PartialClassTwo.cs. return _fname + ", " + _lname;
}
}
}
WebForm.aspx.cs
using System;
namespace WebApplication
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Customer C1 = new Customer();
C1.FName = "Normal";
C1.LName = "Class";
Response.Write("Normal FullName: " + C1.GetFullName() + "</br>");
CusPartialClass C2 = new CusPartialClass();
C2.FName = "Partial";
C2.LName = "Class";
Response.Write("Partial FullName: " + C2.GetFullName());
}
}
}
Part 62 - Creating partial classes
1. All the parts spread across different files, must use the partial keyword.

2. All the parts spread across different files, must have the same access modifiers.

3. If any of the parts are declared abstract, then the entire type is considered abstract.

4. If any of the parts are declared sealed, then the entire type is considered sealed.

5. If any of the parts inherit a class, then the entire type inherits that class.

6. C# does not support multiple class inheritance. Different parts of the partial class must
not specify different base classes.
7. Different parts of the partial class can specify different base interfaces, and the final type
implements all of the interfaces listed by all of the partial declarations.

8. Any members that are declared in a partial definition are available to all of the other
parts of the partial class.

Part 63 - Partial methods


Program.cs PartialClassOne.cs PartialClassTwo.cs
using System; using System; using System;
namespace Program namespace Program namespace Program
{ { {
public partial class Customer public partial class Customer public class MainClass
{ { //The implementation for a {
partial void PartialMtd() partial method is optional public static void Main()
{ partial void PartialMtd(); {
Console.WriteLine("Partial public void NonPartialMtd() Customer C1 = new Customer();
Method Invoked"); { C1.NonPartialMtd();
} Console.WriteLine("NonPartialMethod }
} Invoked"); }
} PartialMtd(); }
}
}
}
1. A partial class or a struct can contain partial methods.
2. A partial method is created using the partial keyword
3. A partial method declaration consists of two parts.
i. The definition (only the method signature)
ii. The implementation.
These may be n separate parts of a partial class, or in the same part.
4. The implementation for a partial method is optional. If we dont provide the
implementation, the compiler removes the signature and all calls to the method.
5. Partial methods are private by default, and it is a compile time error to include any
access modifiers, including private.

6. It is a compile time error, to include declaration and implementation at the same time for
a partial method.
7. A partial method return type must be void. Including any other return type is a compile
time error.

8. Signature of the partial method declaration, must match with the signature of the
implementation.

9. A partial method must be declared within a partial class or partial struct. A non-partial
class or struct cannot include partial methods.

10. A partial method can be implementation only once. Trying to implement a partial
method more than once, raises a compile time error.

Part 64 - How and where are indexers used in .net


To store or retrieve data from session state or application state variables, we use
indexes.
using System;
namespace WebApplication
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{

// Using the string indexer to store session data


Session["Sessionl"] = "Session 1 Data";
Session["Session2"] = "Session 2 Data";
// Using the integral indexer to retrieve data
Response.Write("Session 1 Data = " + Session[0].ToString());
Response.Write("<br/>");
// Using the string indexer to retrieve data
Response.Write("Session 2 Data = " + Session["Session2"].ToString());
}
}
}
If you view the metadata of HttpSessionState class, you can see that there is an integral
and string indexer defined. We use "this" keyword to create indexers in c#. We will
discuss about creating indexers in our next video session.

Another example of indexers usage in .NET. To retrieve data from a specific column
when looping thru Sq1DataReader object, we can use either the integral indexer or
string indexer.
namespace WebApplication
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{

string CS = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
using (Sq1Connection con = new Sq1Connection(CS))
{
Sq1Command cmd = new Sq1Command("Select * from tblEmployee", con);
con.Open();
Sq1DataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
// Using integral indexer to retrieve Id column value
Response.Write("Id = " + rdr[0].ToString() + " ");
// Using string indexer to retrieve Id column value
Response.Write("Name = " + rdr["Name"].ToString());
Response.Write("<br/>");
}
}
}
}
Web.config
<connectionStrings>
<add name="DBCS" connectionString="data source=.;database=Sample;Integrated Security=SSPI"
providerName="System.Data.SqlClient"/>
</connectionStrings>

Right click on SqlDataReader class, to view its metadata. Notice that, there is an integral and
string indexer defined.

What are indexers in C#?


From the above examples, it should be clear that, Indexers allow instances of a class to be
indexed just like arrays.

Next session, we will discuss about creating indexers.

Part 65 - Indexers
Part 66 - Overloading indexers

Part 67 - Optional parameters

Part 68 - Making method parameters optional using method overloading

Part 69 - Making method parameters optional by specifying parameter defaults

Part 70 - Making method parameters optional by using OptionalAttribute

Part 71 - Code snippets in visual studio

Part 72 - What is dictionary

Part 73 - What is dictionary continued


Part 74 - List collection class

Part 75 - List collection class continued

Part 76 - Working with generic list class and ranges

Part 77 - Sort a list of simple types

Part 78 - Sort a list of complex types

Part 79 - Sort a list of complex types using Comparison delegate

Part 80 - Some useful methods of List collection class

Part 81 - When to use a dictionary over list

Part 82 - Generic queue collection class

Part 83 - Generic stack collection class

Part 84 - Real time example of queue collection class

Part 85 - Real time example of stack collection class


Part 86 - Multithreading

Part 87 - Advantages and disadvantages of multithreading

Part 88 - ThreadStart delegate

Part 89 - ParameterizedThreadStart delegate

Part 90 - Passing data to the Thread function in a type safe manner

Part 91 - Retrieving data from Thread function using callback method

Part 92 - Significance of Thread Join and Thread IsAlive functions

Part 93 - Protecting shared resources from concurrent access in multithreading

Part 94 - Difference between Monitor and lock

Part 95 - Deadlock in a multithreaded program

Part 96 - How to resolve a deadlock in a multithreaded program

Part 97 - Performance of a multithreaded program

Part 98 - Anonymous methods


Part 99 - Lambda expression
What are Lambda expressions?
Anonymous methods and Lambda expressions are very similar. Anonymous methods were introduced in
C# 2 and Lambda expressions in C# 3.

To find an employee with Id = 102, using anonymous method


Employee employee = listEmployees.Find(delegate (Employee Emp){ return Emp.ID == 102; });
using System;
using System.Collections.Generic;
class Employee
{
public int ID { get; set; }
public string Name { get; set; }
}
class Sample
{
public static void Main()
{
List<Employee> listEmployees = new List<Employee>();
{
listEmployees.Add(new Employee { ID = 101, Name = "Jessy" });
}
Employee employee = listEmployees.Find(delegate (Employee Emp) { return Emp.ID == 102; });
Console.WriteLine("Employee Details: {0}, {1}", employee.ID, employee.Name);
}
}

To find an employee with Id = 102, using lambda expression


Employee employee = listEmployees.Find(Emp => Emp.ID == 102);

You can also explicitly specify the Input type but not required
Employee employee = listEmployees.Find(Employee Emp) => Emp.ID == 102);

=> is called lambda operator and read as GOES TO. Notice that with Lambda expression you don't have
to use the delegate keyword explicitly and don't have to specify the input parameter type explicitly. The
parameter type is inferred. Lambda expressions are more convenient to use than anonymous methods.
Lambda expressions are particularly helpful for writing LINQ query expressions.

Part 100 - Func delegate

Multithreading
A thread is defined as the execution path of a program. Each thread defines a unique flow of
control. If your application involves complicated and time consuming operations, then it is
often helpful to set different execution paths or threads, with each thread performing a
particular job.
Threads are lightweight processes. One common example of use of thread is implementation
of concurrent programming by modern operating systems. Use of threads saves wastage of
CPU cycle and increase efficiency of an application.
So far we wrote the programs where a single thread runs as a single process which is the
running instance of the application. However, this way the application can perform one job at
a time. To make it execute more than one task at a time, it could be divided into smaller
threads.

Thread Life Cycle


The life cycle of a thread starts when an object of the System.Threading.Thread class is created
and ends when the thread is terminated or completes execution.
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:
o Sleep method has been called
o Wait method has been called
o Blocked by I/O operations
The Dead State: It is the situation when the thread completes execution or is aborted.
The Main Thread
In C#, the System.Threading.Thread class is used for working with threads. It allows creating
and accessing individual threads in a multithreaded application. The first thread to be
executed in a process is called the mainthread.
When a C# program starts execution, the main thread is automatically created. The threads
created using the Thread class are called the child threads of the main thread. You can access
a thread using theCurrentThread property of the Thread class.
The following program demonstrates main thread execution:
using System;
using System.Threading;

namespace MultithreadingApplication
{
class MainThreadProgram
{
static void Main(string[] args)
{
Thread th = Thread.CurrentThread;
th.Name = "MainThread";
Console.WriteLine("This is {0}", th.Name);
Console.ReadKey();
}
}
}

When the above code is compiled and executed, it produces the following result:
This is MainThread

Properties and Methods of the Thread Class


The following table shows some most commonly used properties of theThread class:
Property Description

CurrentContext Gets the current context in which the thread is executing.

CurrentCulture Gets or sets the culture for the current thread.

CurrentPrinciple Gets or sets the thread's current principal (for role-based security).

CurrentThread Gets the currently running thread.

CurrentUICulture Gets or sets the current culture used by the Resource Manager to look up
culture-specific resources at run-time.

ExecutionContext Gets an ExecutionContext object that contains information about the


various contexts of the current thread.

IsAlive Gets a value indicating the execution status of the current thread.

IsBackground Gets or sets a value indicating whether or not a thread is a background


thread.

IsThreadPoolThread Gets a value indicating whether or not a thread belongs to the managed
thread pool.

ManagedThreadId Gets a unique identifier for the current managed thread.

Name Gets or sets the name of the thread.

Priority Gets or sets a value indicating the scheduling priority of a thread.

ThreadState Gets a value containing the states of the current thread.

The following table shows some of the most commonly used methods of theThread class:
Sr.No. Methods

1 public void Abort()


Raises a ThreadAbortException in the thread on which it is invoked, to begin the process
of terminating the thread. Calling this method usually terminates the thread.

2 public static LocalDataStoreSlot AllocateDataSlot()


Allocates an unnamed data slot on all the threads. For better performance, use fields that
are marked with the ThreadStaticAttribute attribute instead.

3 public static LocalDataStoreSlot AllocateNamedDataSlot(string name)


Allocates a named data slot on all threads. For better performance, use fields that are
marked with the ThreadStaticAttribute attribute instead.

4 public static void BeginCriticalRegion()


Notifies a host that execution is about to enter a region of code in which the effects of a
thread abort or unhandled exception might jeopardize other tasks in the application
domain.

5 public static void BeginThreadAffinity()


Notifies a host that managed code is about to execute instructions that depend on the
identity of the current physical operating system thread.

6 public static void EndCriticalRegion()


Notifies a host that execution is about to enter a region of code in which the effects of a
thread abort or unhandled exception are limited to the current task.

7 public static void EndThreadAffinity()


Notifies a host that managed code has finished executing instructions that depend on the
identity of the current physical operating system thread.

8 public static void FreeNamedDataSlot(string name)


Eliminates the association between a name and a slot, for all threads in the process. For
better performance, use fields that are marked with the ThreadStaticAttribute attribute
instead.

9 public static Object GetData(LocalDataStoreSlot slot)


Retrieves the value from the specified slot on the current thread, within the current
thread's current domain. For better performance, use fields that are marked with the
ThreadStaticAttribute attribute instead.

10 public static AppDomain GetDomain()


Returns the current domain in which the current thread is running.

11 public static AppDomain GetDomain()


Returns a unique application domain identifier

12 public static LocalDataStoreSlot GetNamedDataSlot(string name)


Looks up a named data slot. For better performance, use fields that are marked with the
ThreadStaticAttribute attribute instead.

13 public void Interrupt()


Interrupts a thread that is in the WaitSleepJoin thread state.

14 public void Join()


Blocks the calling thread until a thread terminates, while continuing to perform standard
COM and SendMessage pumping. This method has different overloaded forms.

15 public static void MemoryBarrier()


Synchronizes memory access as follows: The processor executing the current thread
cannot reorder instructions in such a way that memory accesses prior to the call to
MemoryBarrier execute after memory accesses that follow the call to MemoryBarrier.

16 public static void ResetAbort()


Cancels an Abort requested for the current thread.

17 public static void SetData(LocalDataStoreSlot slot, Object data)


Sets the data in the specified slot on the currently running thread, for that thread's
current domain. For better performance, use fields marked with the ThreadStaticAttribute
attribute instead.

18 public void Start()


Starts a thread.

19 public static void Sleep(int millisecondsTimeout)


Makes the thread pause for a period of time.

20 public static void SpinWait(int iterations)


Causes a thread to wait the number of times defined by the iterations parameter

21 public static byte VolatileRead(ref byte address)


public static double VolatileRead(ref double address)
public static int VolatileRead(ref int address)
public static Object VolatileRead(ref Object address)
Reads the value of a field. The value is the latest written by any processor in a computer,
regardless of the number of processors or the state of processor cache. This method has
different overloaded forms. Only some are given above.

22 public static void VolatileWrite(ref byte address,byte value)


public static void VolatileWrite(ref double address, double value)
public static void VolatileWrite(ref int address, int value)
public static void VolatileWrite(ref Object address, Object value)
Writes a value to a field immediately, so that the value is visible to all processors in the
computer. This method has different overloaded forms. Only some are given above.

23 public static bool Yield()


Causes the calling thread to yield execution to another thread that is ready to run on the
current processor. The operating system selects the thread to yield to.

Creating Threads
Threads are created by extending the Thread class. The extended Thread class then calls
the Start() method to begin the child thread execution.
The following program demonstrates the concept:
using System;
using System.Threading;

namespace MultithreadingApplication
{
class ThreadCreationProgram
{
public static void CallToChildThread()
{
Console.WriteLine("Child thread starts");
}

static void Main(string[] args)


{
ThreadStart childref = new ThreadStart(CallToChildThread);
Console.WriteLine("In Main: Creating the Child thread");
Thread childThread = new Thread(childref);
childThread.Start();
Console.ReadKey();
}
}
}

When the above code is compiled and executed, it produces the following result:
In Main: Creating the Child thread
Child thread starts

Managing Threads
The Thread class provides various methods for managing threads.
The following example demonstrates the use of the sleep() method for making a thread pause
for a specific period of time.
using System;
using System.Threading;

namespace MultithreadingApplication
{
class ThreadCreationProgram
{
public static void CallToChildThread()
{
Console.WriteLine("Child thread starts");

// the thread is paused for 5000 milliseconds


int sleepfor = 5000;

Console.WriteLine("Child Thread Paused for {0} seconds", sleepfor / 1000);


Thread.Sleep(sleepfor);
Console.WriteLine("Child thread resumes");
}

static void Main(string[] args)


{
ThreadStart childref = new ThreadStart(CallToChildThread);
Console.WriteLine("In Main: Creating the Child thread");
Thread childThread = new Thread(childref);
childThread.Start();
Console.ReadKey();
}
}
}

When the above code is compiled and executed, it produces the following result:
In Main: Creating the Child thread
Child thread starts
Child Thread Paused for 5 seconds
Child thread resumes

Destroying Threads
The Abort() method is used for destroying threads.
The runtime aborts the thread by throwing a ThreadAbortException. This exception cannot be
caught, the control is sent to the finally block, if any.
The following program illustrates this:
using System;
using System.Threading;

namespace MultithreadingApplication
{
class ThreadCreationProgram
{
public static void CallToChildThread()
{
try
{
Console.WriteLine("Child thread starts");

// do some work, like counting to 10


for (int counter = 0; counter <= 10; counter++)
{
Thread.Sleep(500);
Console.WriteLine(counter);
}

Console.WriteLine("Child Thread Completed");


}

catch (ThreadAbortException e)
{
Console.WriteLine("Thread Abort Exception");
}
finally
{
Console.WriteLine("Couldn't catch the Thread Exception");
}
}

static void Main(string[] args)


{
ThreadStart childref = new ThreadStart(CallToChildThread);
Console.WriteLine("In Main: Creating the Child thread");
Thread childThread = new Thread(childref);
childThread.Start();

//stop the main thread for some time


Thread.Sleep(2000);

//now abort the child


Console.WriteLine("In Main: Aborting the Child thread");

childThread.Abort();
Console.ReadKey();
}
}
}

When the above code is compiled and executed, it produces the following result:
In Main: Creating the Child thread
Child thread starts
0
1
2
In Main: Aborting the Child thread
Thread Abort Exception
Couldn't catch the Thread Exception

You might also like