0% found this document useful (0 votes)
17 views156 pages

CSharp File

C# Text Book
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
0% found this document useful (0 votes)
17 views156 pages

CSharp File

C# Text Book
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
Download as pdf or txt
You are on page 1/ 156

1. DOT NET Overview?

.NET is a free, cross-platform, open-source developer platform for building many different types
of applications.

With .NET, you can use multiple languages, editors, and libraries to build for web, mobile,
desktop, games, IoT, and more

2. C#

What is C#?

C# is a simple, modern, object-oriented, and type-safe programming language


Example on Welcome to C# Using Console:

static void Main(string[] args)


{
Console.WriteLine("Hello World!");
Console.ReadLine();
}

3. CLR (Common Language Runtime)

CLR is a runtime environment that manages and executes the code written in any .NET
programming language. CLR is the virtual machine component of the .NET framework. That
language's compiler compiles the source code of applications developed using .NET compliant
languages into CLR's intermediate language called MSIL, i.e., Microsoft intermediate language
code. This code is platform-independent.

It is comparable to byte code in java. Metadata is also generated during compilation and MSIL
code and stored in a file known as the Manifest file. This metadata is generally about members
and types required by CLR to execute MSIL code.

A just-in-time compiler component of CLR converts MSIL code into native code of the machine.
This code is platform-dependent.

CLR manages memory, threads, exceptions, code execution, code safety, verification, and
compilation.

The main components of CLR are:

Common type system


Common language specification
Garbage Collector
Just in Time Compiler (JIT)
Metadata and Assemblies
1. Common type system:

CTS provides guidelines for declaring, using, and managing data types at runtime. It offers cross-
language communication.

2. Common Language Specification (CLS):

Common Language Specification (CLS) contains a set of rules to be followed by all NET-supported
languages. The common rules make it easy to implement language integration and help in cross-
language inheritance and debugging. Each language supported by NET Framework has its own
syntax rules. But CLS ensures interoperability among applications developed using NET languages.

3. Garbage Collection:

Garbage Collector is a component of CLR that works as an automatic memory manager.

4. Just in Time (JIT) Compiler:

JIT Compiler is an important component of CLR. It converts the MSIL code into native code (i.e.,
machine-specific code
5. Metadata & Assemblies:

A Metadata is a binary information about the program, either stored in a CLR Portable Executable
file (PE) along with MSIL code or in the memory.

An assembly is a fundamental unit of physical code grouping. It consists of the assembly manifest,
metadata, MSIL code, and a set of resources like image files. It is also considered a basic
deployment unit, version control, reuse, security permissions, etc.

Managed code:
Any language that is written in the .NET framework is managed code. Managed code use CLR
Unmanaged code:
The code developed outside the .NET framework is known as unmanaged code. Applications
that do not run under the control of the CLR are said to be unmanaged.

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

4. Datatypes

The data types in C# are divided into three types. These are:

Value Data Types

These are integer and floating point based. Some examples of value data types are int, char,
float etc.

Reference Data Types

These data types contain a reference to the variables and not the actual data. Some build in
reference types is object, dynamic and string.

Pointer Data Types

This store the memory address of another data type and the data can be accessed using
pointers.

Value Data Types


A data value can be assigned directly to value data types. They can contain both signed and
unsigned literals. Some of the value data types are int, float and char, which contain integers,
floating point numbers and alphabets respectively.

Below are the Example

bool
byte
char
decimal
double
enum
float
int
long
sbyte
short
struct
uint
ulong
ushort

Reference Data Types

The reference data types contain a reference to the variables and not the actual data stored in
the variables i.e. they refer to a memory location.

Below are the Example


String
Object
Array

Pointer Data Types

The pointer data types in C# store the address of another data type. They are used in an unsafe
context i.e.; an unsafe modifier is required in the program to use pointers.

Example:

using System;
namespace PointerDemo {
class Example {
static unsafe void Main(string[] args) {
int val = 100;
int* ptr = &val;
Console.WriteLine("Data value is: {0} ", val);
Console.WriteLine("Address of the data value is: {0}", (int)ptr);
}
}
}

5. Memory allocation

There are two types of memory allocation for the variables that we created in the .NET
Application i.e., stack memory and heap memory.

Stack
Heap

6. Type Casting

Type conversion is converting one type of data to another type. It is also known as Type Casting.
In C#, type casting has two forms −

Implicit type conversion

These conversions are performed by C# in a type-safe manner. For example, are conversions
from smaller to larger integral types and conversions from derived classes to base classes.

Example:

using System;

namespace TypeConversionApplication {
class ExplicitConversion {
static void Main(string[] args) {
double d = 5673.74;
int i;

// cast double to int.


i = (int)d;
Console.WriteLine(i);
Console.ReadKey();
}
}
}

Explicit type conversion

These conversions are done explicitly by users using the pre-defined functions. Explicit
conversions require a cast operator.
The following example shows an explicit type conversion −

Methods & Description

ToBoolean

Converts a type to a Boolean value, where possible.

ToByte

Converts a type to a byte.

ToChar

Converts a type to a single Unicode character, where possible.


ToDateTime

Converts a type (integer or string type) to date-time structures.

ToDecimal

Converts a floating point or integer type to a decimal type.

ToDouble

Converts a type to a double type.

ToInt16

Converts a type to a 16-bit integer.

ToInt32

Converts a type to a 32-bit integer.

ToInt64

Converts a type to a 64-bit integer.

ToSbyte

Converts a type to a signed byte type.

ToSingle

Converts a type to a small floating point number.

ToString

Converts a type to a string.

ToType

Converts a type to a specified type.

ToUInt16

Converts a type to an unsigned int type.


ToUInt32

Converts a type to an unsigned long type.

ToUInt64

Converts a type to an unsigned big integer.

Example:

using System;

namespace TypeConversionApplication {

class StringConversion {

static void Main(string[] args) {

int i = 75;

float f = 53.005f;

double d = 2345.7652;

bool b = true;

Console.WriteLine(i.ToString());

Console.WriteLine(f.ToString());

Console.WriteLine(d.ToString());

Console.WriteLine(b.ToString());

Console.ReadKey();

}
7. Operators

An operator is a symbol that tells the compiler to perform specific mathematical or logical
manipulations. C# has rich set of built-in operators and provides the following type of operators −

 Arithmetic Operators
 Relational Operators
 Logical Operators
 Assignment Operators
 Misc Operators

Arithmetic Operators
Following table shows all the arithmetic operators supported by C#. Assume variable A holds 10 and
variable B holds 20 then −

Operator Description Example

+ Adds two operands A + B = 30

- Subtracts second operand from the first A - B = -10

* Multiplies both operands A * B = 200

/ Divides numerator by de-numerator B/A=2

% Modulus Operator and remainder of after an integer division B%A=0

++ Increment operator increases integer value by one A++ = 11

-- Decrement operator decreases integer value by one A-- = 9

Relational Operators
Following table shows all the relational operators supported by C#. Assume variable A holds 10 and
variable B holds 20, then −
Operator Description Example

== Checks if the values of two operands are equal or not, if (A == B) is not


yes then condition becomes true. true.

!= Checks if the values of two operands are equal or not, if (A != B) is true.


values are not equal then condition becomes true.

> Checks if the value of left operand is greater than the (A > B) is not
value of right operand, if yes then condition becomes true.
true.

< Checks if the value of left operand is less than the value of (A < B) is true.
right operand, if yes then condition becomes true.

>= Checks if the value of left operand is greater than or equal (A >= B) is not
to the value of right operand, if yes then condition true.
becomes true.

<= Checks if the value of left operand is less than or equal to (A <= B) is true.
the value of right operand, if yes then condition becomes
true.

Logical Operators
Following table shows all the logical operators supported by C#. Assume variable A holds Boolean value
true and variable B holds Boolean value false, then

Operator Description Example

&& Called Logical AND operator. If both the operands are non (A && B) is
zero then condition becomes true. false.

|| Called Logical OR Operator. If any of the two operands is (A || B) is true.


non zero then condition becomes true.
! Called Logical NOT Operator. Use to reverses the logical !(A && B) is
state of its operand. If a condition is true then Logical NOT true.
operator will make false.

Assignment Operators
There are following assignment operators supported by C# −

Operator Description Example

= Simple assignment operator, Assigns values from right C = A + B assigns


side operands to left side operand value of A + B
into C

+= Add AND assignment operator, It adds right operand to C += A is


the left operand and assign the result to left operand equivalent to C =
C+A

-= Subtract AND assignment operator, It subtracts right C -= A is


operand from the left operand and assign the result to equivalent to C =
left operand C-A

*= Multiply AND assignment operator, It multiplies right C *= A is


operand with the left operand and assign the result to equivalent to C =
left operand C*A

/= Divide AND assignment operator, It divides left operand C /= A is


with the right operand and assign the result to left equivalent to C =
operand C/A

%= Modulus AND assignment operator, It takes modulus C %= A is


using two operands and assign the result to left operand equivalent to C =
C%A

<<= Left shift AND assignment operator C <<= 2 is same


as C = C << 2
>>= Right shift AND assignment operator C >>= 2 is same
as C = C >> 2

&= Bitwise AND assignment operator C &= 2 is same as


C=C&2

^= bitwise exclusive OR and assignment operator C ^= 2 is same as


C=C^2

|= bitwise inclusive OR and assignment operator C |= 2 is same as


C=C|2

Miscellaneous Operators
There are few other important operators including sizeof, typeof and ? : supported by C#.

Operator Description Example

sizeof() Returns the size of a data type. sizeof(int), returns 4.

typeof() Returns the type of a class. typeof(StreamReader);

& &a; returns actual


Returns the address of an variable.
address of the variable.

* *a; creates pointer


Pointer to a variable.
named 'a' to a variable.

?: If Condition is true ?
Conditional Expression Then value X : Otherwise
value Y

is If( Ford is Car) // checks


Determines whether an object is of a certain type. if Ford is an object of the
Car class.

as Object obj = new


Cast without raising an exception if the cast fails.
StringReader("Hello");
StringReader r = obj as
StringReader;

8. Boxing and Unboxing

Boxing

The process of converting from a value type to reference type is called boxing

Boxing is an Implicit Conversion

Ex:

int num=123;

object obj=num;

console.WriteLine(obj);

Unboxing

The process of converting from a Reference type to value type is called unboxing

unboxing is an explicit Conversion

Ex :

object obj=123;

int num=(int)obj;

console.writeline(num);

9. C# Keywords

Keywords are predefined sets of reserved words that have special meaning in a program. The
meaning of keywords cannot be changed, neither can they be directly used as identifiers in a
program.

For example,
long mobileNum;

Here, long is a keyword and mobileNum is a variable (identifier). long has a special meaning in
C#

i.e. it is used to declare variables of type long and this function cannot be changed.

Also, keywords like long, int, char, etc cannot be used as identifiers. So, we cannot have
something like:

long long;

C# has a total of 79 keywords.

All these keywords are in lowercase. Here is a complete list of all C# keywords
10. Control/Conditional Statement

C# provides many decision-making statements that help the flow of the C# program based on
certain logical conditions.
Here, you will learn about if, else if, else, and nested if else statements to control the flow based
on the conditions.

types are:

1. if
2. multiple if
3. nested if
4. if else
5. else if

If Statement

The if statement contains a Boolean condition followed by a single or multi-line code block to be
executed. At runtime, if a Boolean condition evaluates to true, then the code block will be
executed, otherwise not.

Syntax:

if(condition)
{
// code block to be executed when if condition evaluates to true
}

Example: if Statement
int i = 10, j = 20;

if (i < j)
{
Console.WriteLine("i is less than j");
}

if (i > j)
{
Console.WriteLine("i is greater than j");
}

else Statement

The else statement can come only after if or else if statement and can be used only once in the
if-else statements. The else statement cannot contain any condition and will be executed when
all the previous if and else if conditions evaluate to false.

Example: else Statement

int i = 20, j = 20;

if (i > j)
{
Console.WriteLine("i is greater than j");
}
else if (i < j)
{
Console.WriteLine("i is less than j");
}
else
{
Console.WriteLine("i is equal to j");
}
Switch Statement

Switch statement can be used to replace the if else and else if statement in C#.
The advantage of using switch over if else and else if statement is the codes will look much
cleaner and readable with switch.

The syntax of switch statement is:

switch (variable/expression)
{
case value1:
// Statements executed if expression(or variable) = value1
break;
case value2:
// Statements executed if expression(or variable) = value1
break;
... ... ...
... ... ...
default:
// Statements executed if no case matches
}

The switch statement evaluates the expression (or variable) and compare its value with the
values (or expression) of each case (value1, value2, …). When it finds the matching value, the
statements inside that case are executed.

But, if none of the above cases matches the expression, the statements inside default block is
executed. The default statement at the end of switch is similar to the else block in if else
statement.

However, a problem with the switch statement is, when the matching value is found, it executes
all statements after it until the end of switch block.

To avoid this, we use break statement at the end of each case. The break statement stops the
program from executing non-matching statements by terminating the execution of switch
statement.

Example :

using System;
namespace _1st_program
{
class Program
{
static void Main(string[] args)
{

char ch;
Console.WriteLine("Enter an alphabet");
ch = Convert.ToChar(Console.ReadLine());

switch (Char.ToLower(ch))
{
case 'a':
Console.WriteLine("Vowel");
break;
case 'e':
Console.WriteLine("Vowel");
break;
case 'i':
Console.WriteLine("Vowel");
break;
case 'o':
Console.WriteLine("Vowel");
break;
case 'u':
Console.WriteLine("Vowel");
break;
default:
Console.WriteLine("Not a vowel");
break;
}

}
}
}

Difference between Switch and If else Example:

using System;

namespace _1st_program
{
class Program
{
static void Main(string[] args)
{

Console.WriteLine("enter a valid number");


string number = Console.ReadLine();
long a = Convert.ToInt64(number);
if (a == 1)
{
Console.WriteLine(a);
}
else if (a == 2)
{
Console.WriteLine(a);
}
else if (a == 3)
{
Console.WriteLine(a);
}
else if (a == 4)
{
Console.WriteLine(a);
}
else
{
Console.WriteLine("Not a valid number");
}

switch (a)
{
case 1:
{
Console.WriteLine(a);
break;
}
case 2:
{
Console.WriteLine(a);
break;
}
case 3:
{
Console.WriteLine(a);
break;
}
case 4:
{
Console.WriteLine(a);
break;
}
default:
Console.WriteLine("Not a valid number");
break;
}

Console.ReadLine();

}
}
}
Practice Example

Simple calculator program using C# switch Statement

11. Loops

for Loop

The for keyword indicates a loop in C#. The for loop executes a block of statements repeatedly
until the specified condition returns false

Syntax:

for (initializer; condition; iterator)


{
//code block
}

The for loop contains the following three optional sections, separated by a semicolon. Those are

Initializer:
The initializer section is used to initialize a variable that will be local to a for loop and
cannot be accessed outside loop. It can also be zero or more assignment statements, method
call, increment, or decrement expression e.g., ++i or i++, and await expression.

Condition:
The condition is a boolean expression that will return either true or false. If an
expression evaluates to true, then it will execute the loop again; otherwise, the loop is exited.

Iterator:
The iterator defines the incremental or decremental of the loop variable
Example for Loop:

// forward numbers

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


{
Console.WriteLine("forward Value of i: {0}", i);
}

// reverse numbers

for (int i = 10; i > 0; i--)


{
Console.WriteLine("reverse Value of i: {0}", i);
}

// Nested Loop

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


{
for (int j = i; j < 4; j++)

Console.WriteLine("Value of i: {0}, J: {1} ", i, j);

While Loop
the while loop to repeatedly execute a block of code as long as the specified condition
returns true.

Syntax:

Initialization;

While(condition)

//code block

Inc/dec

The while loop starts with the while keyword, and it must include a boolean conditional
expression inside brackets that returns either true or false. It executes the code block
until the specified conditional expression returns false.

The for loop contains the initialization and increment/decrement parts. When using the
while loop, initialization should be done before the loop starts, and increment or
decrement steps should be inside the loop.

Example:

int i = 0; // initialization

while (i < 10) // condition

Console.WriteLine("i = {0}", i);

i++; // increment

do while Loop
do while loop is the same as while loop except that it executes the code block at least
once.

Syntax:

Initialization;

do

//code block

//inc/dec

while(condition);

The do-while loop starts with the do keyword followed by a code block and a boolean
expression with the while keyword. The do while loop stops execution exits when a
boolean condition evaluates to false. Because the while(condition) specified at the end
of the block, it certainly executes the code block at least once.

Example

int i = 0;

do

Console.WriteLine("i = {0}", i);

i++;

} while (i < 5);

Break

In c#, Break statement is useful to break or terminate the execution of loops (for, while, do-
while, etc.) or switch statements.
Syntax :

break;

Continue

continue statement is used to terminate the current iteration and start the next iteration

Syntax :

Continue;

Example for above 2

int i;

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


{
if (i == 5)
continue;
if (i == 8)
break;
Console.WriteLine("value is" +i);
}
Console.ReadLine();

Goto

The C# goto statement is also known jump statement.


It is used to transfer control to the other part of the program.
It unconditionally jumps to the specified label.

It can be used to transfer control from deeply nested loop or switch case label.

Note: Currently, it is avoided to use goto statement in C# because it makes the program
complex.

Example:
repeat:
Console.WriteLine("You are not eligible to vote!");

Console.WriteLine("Enter your age:");


int age = Convert.ToInt32(Console.ReadLine());
if (age < 18)
{
goto repeat;
}
else
{
Console.WriteLine("You are eligible to vote!");
}

Logical Programs:

1.Exchange Two integer variable value without using third variable

2.Write a Program Reverse Number - 12345 to 54321 ?

3.Print 1- 100 Prime Numbers ?

4.Fibonacci series?

5. Factorial?

6.Sum of Digits?

7.Armstrong number?

8.Traingle

9.Char Print

10.Palindrome

Arrays

an array is a structure representing a fixed length ordered collection of values or objects with
the same type.

Arrays make it easier to organize and operate on large amounts of data.


For example, rather than creating 100 integer variables, you can just create one array that
stores all those integers!

1.Single Dimensional Array

2.Multidimensional Array

3.Jagged Array

Syntax:

An array can be declared using by specifying the type of its elements with square brackets.

datatype[] arrayName;

Example Array Declaration:

int[] evenNums; // integer array

string [] cities; // string array

Example Array Declaration & Initialization:

int[] evenNums = new int[5]{ 2, 4, 6, 8, 10 };

string[] cities = new string[3]{ "Mumbai", "London", "New York" };

Advantages:

Code Optimization (less code)


Random Access

Easy to sort data etc.

Disadvantages:

Fixed size and must specify the size also

Access Array Elements:

if you want to get the particular value in an array we need to go with Index. based on Index
Value we can get any location value from an array.

so, we can get values in an Array

we can change value in an array

from all using Index

index always Start always with *0*

Examples:

using System;

namespace AccessArray {

class Program {

static void Main(string[] args) {

// create an array

int[] numbers = {1, 2, 3};

//access first element

Console.WriteLine("Element in first index : " + numbers[0]);

//access second element

Console.WriteLine("Element in second index : " + numbers[1]);

//access third element

Console.WriteLine("Element in third index : " + numbers[2]);


Console.ReadLine();

Console.ReadLine();

Change Array Elements:

using System;

namespace ChangeArray {

class Program {

static void Main(string[] args) {

// create an array

int[] numbers = {1, 2, 3};

Console.WriteLine("Old Value at index 0: " + numbers[0]);

// change the value at index 0

numbers[0] = 11;

//print new value

Console.WriteLine("New Value at index 0: " + numbers[0]);

Console.ReadLine();

Iterating C# Array using Loops

using System;

namespace AccessArrayFor {

class Program {

static void Main(string[] args) {

int[] numbers = { 1, 2, 3};

for(int i=0; i < numbers.Length; i++) {

Console.WriteLine("Element in index " + i + ": " + numbers[i]);


}

Console.ReadLine();

if you observe in above array i used .Length

Here, the Length property of the array gives the size of the array.

so you can loop dynamically based on length of the Array.

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

Multidimensional Array

Arrays can have more than one dimension.

In a multidimensional array, each element of the array is also an array. For example,

int[ , ] x = { { 1, 2 ,3}, { 3, 4, 5 } };

Here, x is a multidimensional array which has two elements: {1, 2, 3} and {3, 4, 5}. And, each element of
the array is also an array with 3 elements.

Two-dimensional array in C#

A two-dimensional array consists of single-dimensional arrays as its elements. It can be represented as a


table with a specific number of rows and columns.
Two-Dimensional Array Declaration

int[ , ] x = new int [2, 3];

Two-Dimensional Array initialization

int[ , ] x = { { 1, 2 ,3}, { 3, 4, 5 } };

Access Elements from 2D Array

We use the index number to access elements of a 2D array. For example,

// a 2D array

int[ , ] x = { { 1, 2 ,3}, { 3, 4, 5 } };

// access first element from first row

x[0, 0]; // returns 1

// access third element from second row


x[1, 2]; // returns 5

// access third element from first row

x[0, 2]; // returns 3

Change Array Elements

We can also change the elements of a two-dimensional array. To change the element, we simply assign
a new value to that particular index. For example,

using System;

namespace MultiDArray {

class Program {

static void Main(string[] args) {

int[ , ] numbers = {{2, 3}, {4, 5}};

// old element

Console.WriteLine("Old element at index [0, 0] : "+numbers[0, 0]);

// assigning new value

numbers[0, 0] = 222;

// new element

Console.WriteLine("New element at index [0, 0] : "+numbers[0, 0]);

}
}

out put :

Old element at index [0, 0] : 2

New element at index [0, 0] : 222

Iterating C# Array using Loop

using System;

namespace MultiDArray {

class Program {

static void Main(string[] args) {

int[ , ] numbers = { {2, 3, 9}, {4, 5, 9} };

for(int i = 0; i < numbers.GetLength(0); i++) {

Console.Write("Row "+ i+": ");

for(int j = 0; j < numbers.GetLength(1); j++) {

Console.Write(numbers[i, j]+" ");

Console.WriteLine();
}

Output

Row 0: 2 3 9

Row 1: 4 5 9

In the above example, we have used a nested for loop to iterate through the elements of a 2D array.
Here,

numbers.GetLength(0) - gives the number of rows in a 2D array

numbers.GetLength(1) - gives the number of elements in the row

Jagged Array

a jagged array consists of multiple arrays as its element. However, unlike multidimensional arrays, each
array inside a jagged array can be of different sizes.

C# Jagged Array Declaration

Here's a syntax to declare a jagged array in C#.

dataType[ ][ ] nameOfArray = new dataType[rows][ ];

Let's see an example,

// declare jagged array

int[ ][ ] jaggedArray = new int[2][ ];


Here,

int - data type of the array

[][] - represents jagged array

jaggedArray - name of the jagged array

[2][] - represents the number of elements (arrays) inside the jagged array

Since we know each element of a jagged array is also an array, we can set the size of the individual
array. For example,

// set size of the first array as 3

jaggedArray[0] = new int[3];

// set size of second array as 2

jaggedArray[1] = new int[2];

Here,

index at the first square bracket represents the index of the jagged array element

index at the second square bracket represents the index of the element inside each element of the
jagged array

Initialize without setting size of array elements

declaring string jagged array

int[ ][ ] jaggedArray = new int[2] [ ];

initialize each array

jaggedArray[0] = new int[] {1, 3, 5};

jaggedArray[1] = new int[] {2, 4};

Initialize while declaring Jagged Array


int[ ][ ] jaggedArray = {

new int[ ] {10, 20, 30},

new int[ ] {11, 22},

new int[ ] {88, 99}

};

Accessing elements of a jagged array

We can access the elements of the jagged array using the index number. For example,

// access first element of second array

jaggedArray[1][0];

// access second element of the second array

jaggedArray[1][1];

// access second element of the first array

jaggedArray[0][1];

Example: C# Jagged Array

using System;

namespace JaggedArray {

class Program {

static void Main(string[] args) {

// create a jagged array

int[ ][ ] jaggedArray = {

new int[] {1, 3, 5},

new int[] {2, 4},


};

// print elements of jagged array

Console.WriteLine("jaggedArray[1][0]: " + jaggedArray[1][0]);

Console.WriteLine("jaggedArray[1][1]: " + jaggedArray[1][1]);

Console.WriteLine("jaggedArray[0][2]: " + jaggedArray[0][2]);

Console.ReadLine();

Output

jaggedArray[1][0]: 2

jaggedArray[1][1]: 4

jaggedArray[0][2]: 5

Here, inside a jagged array,

jaggedArray[1][0] - first element of the second array

jaggedArray[1][1] - second element of the second array

jaggedArray[0][2] - third element of the first array

Iterating through a jagged array

In C#, we can use loops to iterate through each element of the jagged array. For example,

using System;
namespace JaggedArray {

class Program {

static void Main(string[] args) {

// declare a jagged array

int[][] jaggedArray = new int[2][];

// set size of Jagged Array Elements

jaggedArray[0] = new int[3];

jaggedArray[1] = new int[2];

// initialize the first array

jaggedArray[0][0] = 1;

jaggedArray[0][1] = 3;

jaggedArray[0][2] = 5;

// initialize the second array

jaggedArray[1][0] = 2;

jaggedArray[1][1] = 2;

// outer for loop

for (int i = 0; i < jaggedArray.Length; i++) {

Console.Write("Element "+ i +": ");

// inner for loop

for (int j = 0; j < jaggedArray[i].Length; j++) {

Console.Write(jaggedArray[i][j] + " ");

}
Console.WriteLine();

Console.ReadLine();

Output

Element 0: 1 3 5

Element 1: 2 2

In the above example, we have used a nested for loop to iterate through the jagged array. Here,

1. Outer for loop

to access the elements (arrays) of the jagged array

jaggedArray.Length - gives the size of jagged array

2. Inner for loop

to access the elements of the individual array inside the jagged array.

jaggedArray[i].Length - gives the size of elements of the ith array inside the jagged array

Compile time and Runtime Errors

Compile Time Errors:

These errors occur when we violate the rules present in a syntax. The compile-time error indicates
something that we need to fix before compiling the code. A compiler can easily detect these errors. It is
the reason why we call them compile-time errors. Here are the most frequent errors (compile-time):
Terminator- missing semicolon.

Missing parenthesis.

Printing the overall value of a variable with no declaration.

Runtime Errors:

These errors occur during the run-time program execution after a successful compilation.

It is very difficult for a compiler to find out a runtime error because it cannot point out the exact line at
which this particular error occurs.

Example:

Divide by Zero

ref vs out

Ref and out keywords in C# are used to pass arguments within a method or function.

Ref Keyword

The ref keyword passes arguments by reference. It means any changes made to this argument in the
method will be reflected in that variable when control returns to the calling method.

Example :

using System;

class RefClass
{

public static void Main()


{

// Assign string value


string str = "Veda";

// Pass as a reference parameter


SetValue(ref str);

// Display the given string


Console.WriteLine(str);
}

static void SetValue(ref string str1)


{

// Check parameter value


if (str1 == "Veda")
{
Console.WriteLine("Hello!!Veda");
}

// Assign the new value


// of the parameter
str1 = "Welcome to Veda";
}
}

Out Keyword :

out is used to state that the parameter passed must be modified by the method

Example:

using System;
class OutClass
{
static public void Main()
{
// Declaring variable
// without assigning value
int G;

// Pass variable G to the method


// using out keyword
Sum(out G);

// Display the value G


Console. WriteLine("The sum of" +" the value is: {0}", G);
}
// Method in which out parameter is passed
// and this method returns the value of
// the passed parameter
public static void Sum(out int G)
{
G = 80;
G += G;
}
}

Note:

ref is two-ways, out is out-only.


Both ref and out parameter treated same at compile-time but different at run-time.

Difference

Object Class
C# is an object-oriented program. In object-oriented programming (OOP), we solve complex problems
by dividing them into objects.

To work with objects, we need to perform the following activities:

create a class

create objects from the class

Class

A class is a Collection of Objects / properties and methods etc.

Syntax for Class:

class ClassName {

Note: In C#, fields and methods inside a class are called members of a class.

C# Objects

An object is an instance of a class.

Suppose, we have a class Veda. StudentName and StudentNumber are the objects of class

Syntax for Object Creation :

ClassName obj = new ClassName();

in the above used "new" keyword to create an object of the class.

And, obj is the name of the object.


Access Class Members using Object

We use the name of objects along with the" ." operator to access members of a class.

Example

using System;

namespace ClassObject {

class Veda

String StudentName{get;set;}
}

static void Main(string[] args) {

// create Veda Object

Veda vda=new Veda();

// access student name of the veda

vda.StudentName = "Raju";

Console.WriteLine(vda.StudentName);

Console.ReadLine();

Creating Multiple Objects of a Class

using System;
namespace ClassObject {

class Employee {

string department;

static void Main(string[] args) {

// create Employee object

Employee sheeran = new Employee();

// set department for sheeran

sheeran.department = "Development";

Console.WriteLine("Sheeran: " + sheeran.department);

// create second object of Employee

Employee taylor = new Employee();

// set department for taylor

taylor.department = "Content Writing";

Console.WriteLine("Taylor: " + taylor.department);

Console.ReadLine();

Creating objects in a different class

We can Create Class in a Class and we can create multiple class in different files and we can use that as
Reference using Name Space

Properties
property is member of class using which we can expose values associated with a class to the outside of
environment

Syntax:

Modifier datatype Name {get; set;}

Example

Public int Marks

get {return marks;} // represents a value returning method without parameter

set{marks=value;} // represents a non-value returning method without parameter

Functions

A method is a block of code that performs a specific task.

Syntax :

returnType methodName()

// method body

returnType - It specifies what type of value a method returns. For example, if a method has an int return
type then it returns an int value.

if the method does not return a value, its return type is void.

methodName - It is an identifier that is used to refer to the particular method in a program.

method body - It includes the programming statements that are used to perform some tasks. The
method body is enclosed inside the curly braces { }

1. Declaring a Method

2. Calling a Method
Example:

using System;

namespace Method {

class Program {

// method declaration

public void display() {

Console.WriteLine("Hello World");

static void Main(string[] args) {

// create class object

Program p1 = new Program();

//call method

p1.display();

Console.ReadLine();

Method Return Type:

A C# method may or may not return a value. If the method doesn't return any value, we use the void
keyword.

If the method returns any value, we use the return statement to return any value.

With void

Void addNumbers() {

...

With Return type

int addNumbers() {

...
return sum;

Example of Method with Return type:

using System;

namespace Method {

class Program {

// method declaration

static int addNumbers() {

int sum = 5 + 14;

return sum;

static void Main(string[] args) {

// call method

int sum = addNumbers();

Console.WriteLine(sum);

Console.ReadLine();

C# Methods Parameters:

we can also create a method that accepts some value. These values are called method parameters.

Example:

int addNumber(int a, int b) {

//code
}

Here, a and b are two parameters passed to the addNumber() function.

If a method is created with parameters, we need to pass the corresponding values(arguments) while
calling the method

// call the method

addNumber(100, 100);

C# Access Modifiers

Access modifiers specify the accessibility of types (classes, interfaces, etc.) and type members (fields,
methods, etc.).

1)public
2)private
3)protected

4)internal
5)protected internal
6)private protected

public: -
When we declare a type or type member public, it can be accessed from anywhere.

Example: -

using System;

namespace MyApplication {

class Student {

public string name = "Sheeran";


public void print() {

Console.WriteLine("Hello from Student class");

class Program {

static void Main(string[] args) {

// creating object of Student class

Student student1 = new Student();sss

// accessing name field and printing it

Console.WriteLine("Name: " + student1.name);

// accessing print method from Student

student1.print();

Console.ReadLine();

// accessing name field and printing it

Console.WriteLine("Name: " + student1.name);

// accessing print method from Student

student1.print();

Private: -

When we declare a type member with the private access modifier, it can only be accessed within the
same class or struct.
Example: -

using System;

namespace MyApplication {

class Student {

private string name = "Sheeran";

private void print() {

Console.WriteLine("Hello from Student class");

class Program

static void Main(string[] args) {

// creating object of Student class

Student student1 = new Student();

// accessing name field and printing it

Console.WriteLine("Name: " + student1.name);

// accessing print method from Student

student1.print();

Console.ReadLine();

}
Protected: -
When we declare a type member as protected, it can only be accessed from the same class and its
derived classes.

Example: -

using System;

namespace MyApplication {

class Student {

protected string name = "Sheeran";

class Program {

static void Main(string[] args) {

// creating object of student class

Student student1 = new Student();

// accessing name field and printing it

Console.WriteLine("Name: " + student1.name);

Console.ReadLine();

Now, let's try to access the protected member from a derived class.

using System;

namespace MyApplication {
class Student {

protected string name = "Sheeran";

// derived class

class Program : Student {

static void Main(string[] args) {

// creating object of derived class

Program program = new Program();

// accessing name field and printing it

Console.WriteLine("Name: " + program.name);

Console.ReadLine();

Internal: -

When we declare a type or type member as internal, it can be accessed only within the same assembly.

Assembly: -

An assembly is a collection of types (classes, interfaces, etc.) and resources (data). They are built to work
together and form a logical unit of functionality. That’s why when we run an assembly all classes and
interfaces inside the assembly run together

using System;

namespace Assembly

{
class Student

internal string name = "Sheeran";

class Program

static void Main(string[] args)

// creating object of Student class

Student theStudent = new Student();

// accessing name field and printing it

Console.WriteLine("Name: " + theStudent.name);

Console.ReadLine();

If we use internal within a single assembly,

it works just like the public access modifier.

Example: internal in different Assembly

using System;

namespace Assembly1 {

public class StudentName {

internal string name = "Sheeran";


}

class Program {

static void Main(string[] args) {

Here, this code is in Assembly1. We have created an internal field name inside the class StudentName.
Now, this field can only be accessed from the same assembly Assembly1.

// Code on Assembly2

using System;

// access Assembly1

using Assembly1;

namespace Assembly2 {

class Program {

static void Main(string[] args) {

StudentName student = new StudentName();

// accessing name field from Assembly1

Console.Write(student.name);

Console.ReadLine();

protected internal: -
The protected internal is a combination of protected and internal access modifiers. When we declare a
member protected internal, it can be accessed from the same assembly and the derived class of the
containing class from any other assembly.

Example:

// Code on Assembly1

using System;

namespace Assembly1 {

public class Greet {

protected internal string msg="Hello";

class Program {

static void Main(string[] args) {

Greet greet = new Greet();

Console.WriteLine(greet.msg);

Console.ReadLine();

In the above example, we have created a class named Greet with a

field msg. Since the field is protected internal, we are able to

access it from the Program class as they are in the same assembly.

Let's derive a class from Greet in another assembly and try to access
the protected internal field msg from it.

// Code on Assembly2

using System;

// access Assembly1

using Assembly1;

namespace Assembly2 {

// derived class of Greet

class Program: Greet {

static void Main(string[] args) {

Program greet = new Program();

// accessing name field from Assembly1

Console.Write(greet.msg);

Console.ReadLine();

private protected: -

The private protected access modifier is a combination of private and protected. It is available from the
C# version 7.2 and later. When we declare a member private protected, it can only be accessed within
the same class, and its derived class within the same assembly.

Example:
// Code in Assembly1

using System;

namespace Assembly1 {

public class StudentName {

private protected string name = "Sheeran";

//derived class of StudentName class

class Program1 : StudentName {

static void Main(string[] args) {

Program1 student = new Program1();

// accessing name field from base class

Console.Write(student.name);

Console.ReadLine();

Scope of Variables

A variable scope refers to the availability of variables in certain parts of the code.

we have 3 variable types:


1.Class Level Variable Scope

2.Method Level Variable Scope

3.Block Level Variable Scope

1.Class Level Variable Scope:

when we declare a variable inside a class, the variable can be accessed within the class.

2.Method Level Variable Scope:

When we declare a variable inside a method, the variable cannot be accessed outside of the method.

3.Block Level Variable Scope:

When we declare a variable inside a block (for loop, while loop, if. Else), the variable can only be
accessed within the block.

Example:

using System;

namespace VariableScope
{
class Program
{

string ClassVariable = "Class Level";


public void display()
{
// with in the class
Console.WriteLine(ClassVariable);

string MethodVariable = "Method Level";

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


{
// with in the method
Console.WriteLine(MethodVariable);

// with in the block


Console.WriteLine(i);
}
// out side of the block
//Console.WriteLine(i);
}
// out side of the method
//Console.WriteLine(MethodVariable);

static void Main(string[] args)


{
Program ps = new Program();
ps.display();

Console.ReadLine();
}
}

//out side of the class


//Console.WriteLine(ClassVariable);
}

Constructor

A constructor is similar to a method that is invoked when an object of the class is created.

1. Constructor Name and Class Name must be same

2. Constructor does not have any return type

How To Create a Constructor:

class Student

Student ()

//code

}
Student () is the Constructor

Call a constructor:

just create an object for class

Student student = new Student();

or call directly like below

new Student();

Types of Constructors

1. Parameterless Constructor

2. Parameterized Constructor

3. Default Constructor

1. Parameterless Constructor

When we create a constructor without parameters, it is known as a parameter less constructor.

Example:

using System;

namespace Constructor {

class Car {
// parameterless constructor

Car()

Console.WriteLine("Car Constructor");

static void Main(string[] args) {

// call constructor

new Car();

Console.ReadLine();

2. Parameterized Constructor

a constructor can also accept parameters. It is called a parameterized constructor.

Example:

using System;

namespace Constructor

class Car

string brand;

int price;

// parameterized constructor
Car(string theBrand, int thePrice)

brand = theBrand;

price = thePrice;

static void Main(string[] args)

// call parameterized constructor

Car car1 = new Car("Swift", 900000);

Console.WriteLine("Brand: " + car1.brand);

Console.WriteLine("Price: " + car1.price);

Console.ReadLine();

3. Default Constructor

If we have not defined a constructor in our class, then the C# will automatically create a default
constructor with an empty code and no parameters.

Example:
using System;
namespace Constructor
{
class Program
{
int i;
string s;
static void Main(string[] args)
{
// call default constructor
Program p1 = new Program();
Console.WriteLine("Default value of a: " + p1.i);
Console.WriteLine("Default value of a: " + p1.s);
Console.ReadLine();
}
}
}

Here:

we have not created any constructor in the Program class. However, while creating an object, we are
calling the constructor.

Program p1 = new Program();

C# automatically creates a default constructor. The default constructor initializes any uninitialized
variable with the default value.

Hence, we get 0 as the value of the int variable a.

Note: In the default constructor, all the numeric fields are initialized to 0, whereas string and object are
initialized as null.

4. Copy Constructor

The copy constructor is used to initialize the members of a newly created object by copying the
members of an already existing object.

Example:

using System;

namespace Constructor

class Car

string brand;

// constructor

Car(string theBrand)

{
brand = theBrand;

Console.WriteLine("Brand of car1: " + brand);

// copy constructor

Car(Car c1)

brand = c1.brand;

Console.WriteLine("Brand of car2: " + brand);

static void Main(string[] args)

// call constructor

Car car1 = new Car("Swift");

// call the copy constructor

Car car2 = new Car(car1);

Console.ReadLine();

Explanation of Example:

In the above program, we have used a copy constructor.

Car(Car c1) {

brand = c1.brand;

Here, this constructor accepts an object of Car as its parameter. So, when creating the car2 object, we
have passed the car1 object as an argument to the copy constructor.

Car car2 = new Car(car1);

Inside the copy constructor, we have assigned the value of the brand for car1 object to the brand
variable for car2 object. Hence, both objects have the same value of the brand.
5. Private Constructor

We can create a private constructor using the private access specifier. This is known as a private
constructor.

Once the constructor is declared private, we cannot create objects of the class in other classes.

Example:

using System;

namespace Constructor {

class Car {

// private constructor

private Car () {

Console.WriteLine("Private Constructor");

class CarDrive {

static void Main(string[] args) {

// call private constructor

Car car1 = new Car();

Console.ReadLine();

}}

Note:

If a constructor is private, we cannot create objects of the class. Hence, all fields and methods of the
class should be declared static, so that they can be accessed using the class name.

6. Static Constructor

we can also make our constructor static. We use the static keyword to create a static constructor.

Example:

using System;
namespace Constructor {

class Car {

// static constructor

static Car () {

Console.WriteLine("Static Constructor");

// parameterless constructor

Car() {

Console.WriteLine("Default Constructor");

static void Main(string[] args) {

// call parameterless constructor

Car car1 = new Car();

// call parameterless constructor again

Car car2 = new Car();

Console.ReadLine();

Explanation of Example:

In the above example, we have created a static constructor.

static Car () {

Console.WriteLine("Static Constructor");

We cannot call a static constructor directly. However, when we call a regular constructor, the static
constructor gets called automatically.
Car car1 = new Car();

Here, we are calling the Car() constructor. You can see that the static constructor is also called along
with the regular constructor.

The static constructor is called only once during the execution of the program. That's why when we call
the constructor again, only the regular constructor is called.

Note: We can have only one static constructor in a class. It cannot have any parameters or access
modifiers.

this Keyword

this keyword refers to the current instance of a class.

Example:

using System;

namespace ThisKeyword {

class Test {

int num;

Test(int num) {

// this.num refers to the instance field

this.num = num;

Console.WriteLine("object of this: " + this);

static void Main(string[] args) {

Test t1 = new Test(4);

Console.WriteLine("object of t1: " + t1);

Console.ReadLine();

}
}

In the above example, we have created an object named t1 of the class Test. We have printed the name
of the object t1 and this keyword of the class.

Here, we can see the name of both t1 and this is the same. This is because this keyword refers to the
current instance of the class which is t1.

same variable example:

using System;

namespace ThisKeyword {

class Test {

int num;

Test(int num) {

num = num;

static void Main(string[] args) {

Test t1 = new Test(4);

Console.WriteLine("value of num: " + t1.num);

Console.ReadLine();

}}

In the above program, the instance variable and the parameter have the same name: num. We have
passed 4 as a value to the constructor.

However, we are getting 0 as an output. This is because the C# gets confused because the names of the
instance variable and the parameter are the same.

We can solve this issue by using this.


using System;

namespace ThisKeyword {

class Test {

int num;

Test(int num) {

// this.num refers to the instance field

this.num = num;

static void Main(string[] args) {

Test t1 = new Test(4);

Console.WriteLine("value of num: " +t1.num);

Console.ReadLine();

Now, we are getting the expected output that is 4. It is because this.num refers to the instance variable
of the class.

static Keyword

if we use a static keyword with class members, then there will be a single copy of the type member.

And, all objects of the class share a single copy instead of creating individual copies.

Static Variables:

If a variable is declared static, we can access the variable using the class name.

Example:
using System;

namespace StaticKeyword {

class Student {

// static variable

public static string department = "Computer Science";

class Program {

static void Main(string[] argos) {

// access static variable

Console.WriteLine("Department: " + Student.department);

Console.ReadLine();

Instance Variables

every object of a class will have its own copy of instance variables.

class Student {

// instance variable

public string studentName;

class Program {

static void Main(string[] args) {

Student s1 = new Student();

Student s2 = new Student();

Static Variable Vs. Instance Variable


Example:

using System;

namespace StaticKeyword {

class Student {

static public string schoolName = "Programiz School";

public string studentName;

class Program {

static void Main(string[] args) {

Student s1 = new Student();

s1.studentName = "Ram";

// calls instance variable

Console.WriteLine("Name: " + s1.studentName);

// calls static variable

Console.WriteLine("School: " + Student.schoolName);

Student s2 = new Student();

s2.studentName = "Shyam";

// calls instance variable

Console.WriteLine("Name: " + s2.studentName);

// calls static variable

Console.WriteLine("School: " + Student.schoolName);

Console.ReadLine();

Explanation for Example:


In the above program, the Student class has a non-static variable named studentName and a static
variable named schoolName.

Inside the Program class,

s1.studentName / s2.studentName - calls the non-static variable using objects s1 and s2 respectively

Student.schoolName - calls the static variable by using the class name

Since the schoolName is the same for all students, it is good to make the schoolName static. It saves
memory and makes the program more efficient.

Static Methods:

we can call the static methods using the class name.

Example:

class Test {

public static void display() {....}

class Program {

static void Main(string[] args) {

Test.display();

Static and Non-static Methods

using System;

namespace StaticKeyword {

class Test {

public void display1() {


Console.WriteLine("Non static method");

public static void display2() {

Console.WriteLine("Static method");

class Program {

static void Main(string[] args) {

Test t1 = new Test();

t1.display1();

Test.display2();

Console.ReadLine();

} }}

In the above program, we have declared a non-static method named display1() and a static method
named display2() inside the class Test.

Inside the Program class,

t1.display1() - access the non-static method using s1 object

Test.display2() - access the static method using the class name Test

Note: In C#, the Main method is static. So, we can call it without creating the object.

Static Class

when we declare a class as static, we cannot create objects of the class and We cannot inherit a static
class

Example:

using System;

namespace StaticKeyword {

static class Test {


static int a = 5;

static void display() {

Console.WriteLine("Static method");

static void Main(string[] args) {

// creating object of Test

Test t1 = new Test();

Console.WriteLine(a);

display();

Explanation:

In the above example, we have a static class Test. We have created an object t1 of the class Test.

Since we cannot make an object of the static class, we get the following error:

error CS0723: Cannot declare a variable of static type 'Test'

error CS0712: Cannot create an instance of the static class

Notice the field and method of the static class are also static because we can only have static members
inside the static class.

Note: We cannot inherit a static class in C#. For example,

static class A {

...

// Error Code

class B : A {

...
}

If we are accessing the static variables and methods inside the same class, we can directly access them
without using the class name

Example:

using System;

namespace StaticKeyword {

class Test {

static int age = 25;

public static void display() {

Console.WriteLine("Static method");

static void Main(string[] args) {

Console.WriteLine(age);

display();

Console.ReadLine();

Strings

Methods Description

Format() returns a formatted string

Split() splits the string into substring

Substring() returns substring of a string


Compare() compares string objects

Replace() replaces the specified old character with the specified new character

Contains() checks whether the string contains a substring

Join() joins the given strings using the specified separator

Trim() removes any leading and trailing whitespaces

EndsWith() checks if the string ends with the given string

IndexOf() returns the position of the specified character in the string

Remove() returns characters from a string

ToUpper() converts the string to uppercase

ToLower() converts the string to lowercase

PadLeft() returns string padded with spaces or with a specified Unicode character on the left

PadRight() returns string padded with spaces or with a specified Unicode character on the right

StartsWith() checks if the string begins with the given string

ToCharArray() converts the string to a char array

LastIndexOf() returns index of the last occurrence of a specified string


OOPS

Encapsulation:

It is the mechanism of wrapping the data (variables) and code acting on the
data(methods) together as a single unit.

The process of defining a class by hiding its internal data members from outside the class and accessing
those internal data members only through publicly exposed methods (setter and getter methods) or
properties with proper validations is called encapsulation.

Note: Data encapsulation is also called data hiding because by using this principle we can hide the
internal data from outside the class.

How to achieve Encapsulation:

* Declare the variables of a class as private. (Data hiding)

* Provide public setter and getter methods to modify and view the variables values.

ex:

class Account

private int accountBalance = 1000;

public void SetBalance(int amount)

if(amount<0 )

Console.WriteLine("Your amount must be in positive values");

else

accountBalance = amount;
}

accountBalance = amount;

public void GetBalance()

Console.WriteLine("Your Account Balance is:" + accountBalance);

class Program

static void Main(string[] args)

Account MyAccount = new Account();

MyAccount.SetBalance(100);

MyAccount.GetBalance();

Console.ReadLine();

Advantages:

• Protection of data from accidental corruption.

• Specification of the accessibility of each of the members of a class to the code outside the class.

• Flexibility and extensibility of the code and reduction in complexity.

• Achieving Data Hiding. The user will have no idea about the inner implementation of the class.
• Encapsulation also improves the re-usability and easy to change with new requirements.

Abstraction

Hiding the Complexity. It means that only the required information is visible to the user and the rest of
the information is hidden.

Abstraction can be implemented using abstract classes in C#.

Abstract classes are base classes with partial implementation

Abstract class:

A class under which we declare abstract members is known as abstract class and must be declared by
using “abstract” modifier.

It is a restricted class that cannot be used to create objects (to access it, it must be inherited
from another class).

Abstract method:

It can only be used in an abstract class, and it does not have a body. The body is provided by the derived
class (inherited from).

a method without any body is known as abstract method i.e. an abstract method contains only
declaration without any implementation.

To declare a method as abstract it is must to use “abstract” modifier on that method explicitly.

Example:

abstract class Language {

// abstract method

public abstract void display1();

// non-abstract method

public void display2() {

Console.WriteLine("Non abstract method");


}

Inheritance

Inheritance allows you to access members of base class in child class. It enables you to create a
child class that can access and use all the functionality of its base class. This way you can keep common
variable and functions in a base class and use them as many times as you want in child class. Code
reusability makes your program simpler and efficient.

Syntax:

<access_modifier> class <base_class_name>

// Base class Implementation

<access_modifier> class <derived_class_name>: <base_class_name>

// Derived class implementation

C# Multi-Level Inheritance Example:

using System;

namespace Tutlane

public class A

public string Name;

public void GetName()

{
Console.WriteLine("Name: {0}", Name);

public class B: A

public string Location;

public void GetLocation()

Console.WriteLine("Location: {0}", Location);

public class C: B

public int Age;

public void GetAge()

Console.WriteLine("Age: {0}", Age);

class Program

static void Main(string[] args)

C c = new C();

c.Name = "Suresh Dasari";

c.Location = "Hyderabad";

c.Age = 32;

c.GetName();

c.GetLocation();
c.GetAge();

Console.WriteLine("\nPress Any Key to Exit..");

Console.ReadLine();

C# Multiple Inheritance

As discussed, c# supports only single inheritance that means a class can only inherit from one base class.
If we try to inherit a class from multiple base classes, then we will get compile-time errors.

For example, if class C is trying to inherit from Class A and B simultaneously, we will get a compile-time
error because multiple inheritance is not allowed in c#.

public class A

// Implementation

public class B

// Implementation

public class C: A, B

// Implementation

}
If you observe the above code snippet, class C is trying to inherit properties from both classes A and B
simultaneously, which will lead to compile-time errors like “Class C cannot have multiple classes: A and
B”.

As discussed, multi-level inheritance is supported in c#, but multiple inheritance is not supported. If you
want to implement multiple inheritance in c#, we can achieve this by using interfaces.

Interface

an interface is similar to abstract class. However, unlike abstract classes, all methods of an interface are
fully abstract (method without body).

we need to Declare Interface with interface keyword to create an interface.

Syntax :

interface Operators{

// method without body

void Add();

Operators is the name of the interface.

interface starts with I so that we can identify it just by seeing its name.

We cannot use access modifiers inside an interface.

All members of an interface are public by default

An interface doesn't allow fields.


We cannot create objects of an interface. To use an interface, other classes must implement it. Same as
in C# Inheritance, we use : symbol to implement an interface

Example :

using System;

namespace CsharpInterface

interface Operators

// method without body

void Add(int a, int b);

class AddMethod : Operators

public void Add(int a, int b)

int result = a + b;

Console.WriteLine(result);

class Program

static void Main(string[] args)


{

AddMethod addmethod = new AddMethod();

addmethod.Add(100, 200);

Multiple Inheritence

using System;

namespace CsharpInterface

interface AddOperators

// method without body

void Add(int a, int b);

interface SubOperators

// method without body

void Sub(int a, int b);

class AddMethod : AddOperators, SubOperators

{
public void Add(int a, int b)

int result = a + b;

Console.WriteLine(result);

public void Sub(int a, int b)

int result = a - b;

Console.WriteLine(result);

class Program

static void Main(string[] args)

AddMethod addmethod = new AddMethod();

addmethod.Add(100, 200);

addmethod.Sub(200, 100);

}}

Polymorphism

The term "Polymorphism" is the combination of "poly" + "morphs" which means many forms. It is a
greek word.

There are two types of polymorphism in C#.

1.compile time polymorphism


2.runtime polymorphism

1.compile time polymorphism

Compile time polymorphism is achieved by method overloading and operator overloading in C#

It is also known as static binding or early binding.

2.runtime polymorphism

Runtime polymorphism in achieved by method overriding which is also known as dynamic binding or
late binding.

Overloading:

If we create two or more members having same name but different in number or type of parameter, it is
known as member overloading.

we can overload:

methods,

constructors

Having two or more methods with same name but different in parameters, is known as method
overloading in C#.

The advantage of method overloading is that it increases the readability of the program because you
don't need to use different names for same action.

we can achieve method overloading in different ways:

By changing number of arguments

By changing data type of the arguments

By changing the Data types of the parameters

By changing the Order of the parameters


Examples: By changing number of arguments

using System;

public class Cal{

public static int add(int a,int b){

return a + b;

public static int add(int a, int b, int c)

return a + b + c;

public class TestMemberOverloading

public static void Main()

Console.WriteLine(Cal.add(12, 23));

Console.WriteLine(Cal.add(12, 23, 25));

Examples: By changing data type of arguments

using System;

public class Cal{

public static int add(int a, int b){

return a + b;

public static float add(float a, float b)


{

return a + b;

public class TestMemberOverloading

public static void Main()

Console.WriteLine(Cal.add(12, 23));

Console.WriteLine(Cal.add(12.4f,21.3f));

Overriding

Defining Multiple Methods with same name and same signature is called method overriding

Example

using System;

public class ParentClass

public virtual void PrintStudentName()

Console.WriteLine("Veda");

public class ChildClass : ParentClass

public override void PrintStudentName()

{
Console.WriteLine("veda institute...");

public class TestOverriding

public static void Main()

ChildClass print = new ChildClass();

print.PrintStudentName();

Difference

Sealed

C# sealed keyword applies restrictions on the class and method. If you create a sealed class, it cannot be
derived. If you create a sealed method, it cannot be overridden.

Example:

using System;

sealed public class Animal

{
public void eat() { Console.WriteLine("eating..."); }

public class Dog : Animal

public void bark() { Console.WriteLine("barking..."); }

public class TestSealed

public static void Main()

Dog d = new Dog();

d.eat();

d.bark();

Example on Method:

using System;

public class ParentClass

public virtual void PrintStudentName()

Console.WriteLine("Veda");

public class ChildClass : ParentClass

public sealed override void PrintStudentName()


{

Console.WriteLine("veda institute...");

public class SubChildClass : ChildClass

public override void PrintStudentName()

Console.WriteLine("veda institute...");

public class TestOverriding

public static void Main()

ChildClass print = new ChildClass();

print.PrintStudentName();

Partial Class

A partial class is a special feature of C#. It provides a special ability to implement the functionality of a
single class into multiple files and all these files are combined into a single class file when the application
is compiled. A partial class is created by using a partial keyword.

Syntax :
public partial Clas_name

// code

Example:

public partial class Employee

public int EmpId { get; set; }

public string Name { get; set; }

public partial class Employee

public int EmpNumber { get; set; }

public string EmpAddress { get; set; }

virtual

The virtual keyword is used to modify a method, property, indexer, or event declaration and allow for it
to be overridden in a derived class. For example, this method can be overridden by any class that
inherits it:

Example:

using System;

public class ParentClass

public virtual void PrintStudentName()

{
Console.WriteLine("Veda");

public class ChildClass : ParentClass

public override void PrintStudentName()

Console.WriteLine("veda institute...");

public class TestOverriding

public static void Main()

ChildClass print = new ChildClass();

print.PrintStudentName();

When a virtual method is invoked, the run-time type of the object is checked for an overriding member.
The overriding member in the most derived class is called, which might be the original member, if no
derived class has overridden the member.

By default, methods are non-virtual. You cannot override a non-virtual method.

You cannot use the virtual modifier with the static, abstract, private, or override modifiers.

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

Base
base keyword is used to access fields, constructors and methods of base class.

You can use base keyword within instance method, constructor or instance property accessor only. You
can't use it inside the static method.

Example of accessing base class field

We can use the base keyword to access the fields of the base class within derived class. It is useful if
base and derived classes have the same fields. If derived class doesn't define same field, there is no
need to use base keyword. Base class field can be directly accessed by the derived class.

using System;

public class Animal{

public string color = "white";

public class Dog: Animal

string color = "black";

public void showColor()

Console.WriteLine(base.color);

Console.WriteLine(color);

public class TestBase

public static void Main()

{
Dog d = new Dog();

d.showColor();

Example on calling base class method

By the help of base keyword, we can call the base class method also. It is useful if base and derived
classes define same method. In other words, if method is overridden. If derived class doesn't define
same method, there is no need to use base keyword. Base class method can be directly called by the
derived class method.

using System;

public class Animal{

public virtual void eat(){

Console.WriteLine("eating...");

public class Dog: Animal

public override void eat()

base.eat();

Console.WriteLine("eating bread...");

public class TestBase

public static void Main()


{

Dog d = new Dog();

d.eat();

Example on calling base class constructor internally

Whenever you inherit the base class, base class constructor is internally invoked. Let's see the example
of calling base constructor.

using System;

public class Animal{

public Animal(){

Console.WriteLine("animal...");

public class Dog: Animal

public Dog()

Console.WriteLine("dog...");

public class TestOverriding

public static void Main()

Dog d = new Dog();


}

Method Hiding

C# also provides a concept to hide the methods of the base class from derived class, this concept is
known as Method Hiding. It is also known as Method Shadowing. In method hiding, you can hide the
implementation of the methods of a base class from the derived class using the new keyword. Or in
other words, in method hiding, you can redefine the method of the base class in the derived class by
using the new keyword.

Example:

using System;

public class My_Family

public void member()

Console.WriteLine("Total number of family members: 3");

public class My_Member : My_Family

public new void member()

Console.WriteLine("Name: Rakesh, Age: 40 \nName: Somya, " +

"Age: 39 \nName: Rohan, Age: 20 ");

}
class GFG

static public void Main()

// Creating the object of the derived class

My_Member obj = new My_Member();

// Access the method of derived class

obj.member();

By using the base keyword, you can call the hidden method of the base class in your derived class shown
in the below example:

using System;

// Base Class

public class My_Family {

public void member()

Console.WriteLine("Total number of family members: 3");

// Derived Class
public class My_Member : My_Family {

public new void member()

// Calling the hidden method of the

// base class in a derived class

// Using base keyword

base.member();

Console.WriteLine("Name: Rakesh, Age: 40 \nName: Somya,"+

" Age: 39 \nName: Rohan, Age: 20");

class GFG {

// Main method

static public void Main()

// Creating the object of the derived class

My_Member obj = new My_Member();

// Access the method of derived class

obj.member();

}
Exception Handling

it is a process to handle runtime errors. We perform exception handling so that normal flow of the
application can be maintained even after runtime errors.

exception is an event or object which is thrown at runtime. All exceptions the derived from
System.Exception class.

Advantages:

It maintains the normal flow of the application. In such case, rest of the code is executed event after
exception.
Exception Classes:

System.DivideByZeroException

handles the error generated by dividing a number with zero.

System.NullReferenceException

handles the error generated by referencing the null object.

System.InvalidCastException

handles the error generated by invalid typecasting.

System.IO.IOException

handles the Input Output errors.

System.FieldAccessException

handles the error generated by invalid private or protected field access.

Exception Handling Keywords:

try

catch

finally, and

throw

try & catch:

exception handling is performed by try/catch statement. The try block in C# is used to place the code
that may throw exception. The catch block is used to handle the exception. The catch block must be
preceded by try block.

Example:

using System;

public class Example

public static void Main(string[] args)


{

try

int a = 10;

int b = 0;

int x = a / b;

catch (Exception e) { Console.WriteLine(e); }

Console.WriteLine("Rest of the code");

Example 2:

using System;

namespace ErrorHandlingApplication

class DivNumbers

int result;

DivNumbers()

result = 0;

public void division(int num1, int num2)

try

result = num1 / num2;


}

catch (DivideByZeroException e)

Console.WriteLine("Exception caught: {0}", e);

finally

Console.WriteLine("Result: {0}", result);

static void Main(string[] args)

DivNumbers d = new DivNumbers();

d.division(25, 0);

Console.ReadKey();

User-Defined Exceptions:

C# allows us to create user-defined or custom exception. It is used to make the meaningful exception.
To do this, we need to inherit Exception class.

using System;

public class InvalidAgeException : Exception

public InvalidAgeException(String message)

: base(message)

}
}

public class TestUserDefinedException

static void validate(int age)

if (age < 18)

throw new InvalidAgeException("Sorry, Age must be greater than 18");

public static void Main(string[] args)

try

validate(12);

catch (InvalidAgeException e) { Console.WriteLine(e); }

Console.WriteLine("Rest of the code");

Collections

collection represents group of objects. By the help of collections, we can perform various operations on
objects such as

store object

update object
delete object

retrieve object

search object, and

sort object

We can store objects in array or collection. Collection has advantage over array. Array has size limit but
objects stored in collection can grow dynamically.

Types of Collections:

System.Collections.Generic classes

System.Collections classes (Now deprecated)

System.Collections.Concurrent classes

System.Collections.Generic:

1.List

2.Stack

3.Queue

4.LinkedList

5.HashSet

6.SortedSet

7.Dictionary

8.SortedDictionary

9.SortedList

System.Collections :

1.ArrayList

2.Hashtable
System.Collections.Concurrent :

The System.Collections.Concurrent provides some collection classes that help to achieve thread-safe
code.

There can be situations when multiple threads are trying to execute the same piece of code. The code is
said to be "thread-safe" if it can be executed correctly irrespective of multiple threads accessing
concurrently

It is recommended to use System.Collections.Concurrent classes rather than System.Collections and


System.Collections.Generic classes when multiple threads are accessing the collection.

Some of the thread-safe collection classes are:

ConcurrentStack<T>

ConcurrentQueue<T>

ConcurrentDictionary<TKey,TValue>

foreach

The foreach loop in C# executes a block of code on each element in an array or a collection of items.

Syntax:

foreach (element in iterable-item)

// body of foreach loop

The in keyword used along with foreach loop is used to iterate over the iterable-item. The in keyword
selects an item from the iterable-item on each iteration and store it in the variable element.

On first iteration, the first item of iterable-item is stored in element. On second iteration, the second
element is selected and so on.
The number of times the foreach loop will execute is equal to the number of elements in the array or
collection.

Example:

using System;

namespace Loop

class ForEachLoop

public static void Main(string[] args)

char[] myArray = {'H','e','l','l','o'};

foreach(char ch in myArray)

Console.WriteLine(ch);

List<T>

List<T> class is used to store and fetch elements. It can have duplicate elements.

List<T> class that stores elements using Add() method and iterates the list using for-each loop.
Example :

using System;

using System.Collections.Generic;

public class ListExample

public static void Main(string[] args)

// Create a list of strings

var names = new List<string>();

names.Add("Sonoo Jaiswal");

names.Add("Ankit");

names.Add("Peter");

names.Add("Irfan");

// Iterate list element using foreach loop

foreach (var name in names)

Console.WriteLine(name);

Example 2:

using System;

using System.Collections.Generic;
public class ListExample

public static void Main(string[] args)

// Create a list of strings using collection initializer

var names = new List<string>() {"Sonoo", "Vimal", "Ratan", "Love" };

// Iterate through the list.

foreach (var name in names)

Console.WriteLine(name);

HashSet<T>

HashSet class can be used to store, remove or view elements. It does not store duplicate elements. It is
suggested to use HashSet class if you have to store only unique element.

HashSet<T> class that stores elements using Add() method and iterates elements using for-each loop

Example :

using System;

using System.Collections.Generic;

public class HashSetExample


{

public static void Main(string[] args)

// Create a set of strings

var names = new HashSet<string>();

names.Add("Sonoo");

names.Add("Ankit");

names.Add("Peter");

names.Add("Irfan");

names.Add("Ankit");//will not be added

// Iterate HashSet elements using foreach loop

foreach (var name in names)

Console.WriteLine(name);

With Collection initializer.

Example :

using System;

using System.Collections.Generic;

public class HashSetExample

{
public static void Main(string[] args)

// Create a set of strings

var names = new HashSet<string>(){"Sonoo", "Ankit", "Peter", "Irfan"};

// Iterate HashSet elements using foreach loop

foreach (var name in names)

Console.WriteLine(name);

SortedSet<T>

SortedSet class can be used to store, remove or view elements. It maintains ascending order and does
not store duplicate elements. It is suggested to use SortedSet class if you have to store unique elements
and maintain ascending order.

SortedSet<T> class that stores elements using Add() method and iterates elements using for-each loop.

Example :

using System;

using System.Collections.Generic;

public class SortedSetExample

{
public static void Main(string[] args)

// Create a set of strings

var names = new SortedSet<string>();

names.Add("Sonoo");

names.Add("Ankit");

names.Add("Peter");

names.Add("Irfan");

names.Add("Ankit");//will not be added

// Iterate SortedSet elements using foreach loop

foreach (var name in names)

Console.WriteLine(name);

With Collection initializer:

Example:

using System;

using System.Collections.Generic;

public class SortedSetExample

public static void Main(string[] args)


{

// Create a set of strings

var names = new SortedSet<string>(){"Sonoo", "Ankit", "Peter", "Irfan"};

// Iterate SortedSet elements using foreach loop

foreach (var name in names)

Console.WriteLine(name);

Stack<T>

Stack<T> class is used to push and pop elements. It uses the concept of Stack that arranges elements in
LIFO (Last in First Out) order. It can have duplicate elements.

Stack<T> class that stores elements using Push() method, removes elements using Pop() method and
iterates elements using for-each loop.

Example :

using System;

using System.Collections.Generic;

public class StackExample

public static void Main(string[] args)


{

Stack<string> names = new Stack<string>();

names.Push("Sonoo");

names.Push("Peter");

names.Push("James");

names.Push("Ratan");

names.Push("Irfan");

foreach (string name in names)

Console.WriteLine(name);

Console.WriteLine("Peek element: "+names.Peek());

Console.WriteLine("Pop: "+ names.Pop());

Console.WriteLine("After Pop, Peek element: " + names.Peek());

Queue<T>

Queue<T> class is used to Enqueue and Dequeue elements. It uses the concept of Queue that arranges
elements in FIFO (First In First Out) order. It can have duplicate elements.

Queue<T> class that stores elements using Enqueue() method, removes elements using Dequeue()
method and iterates elements using for-each loop.

Example :
using System;

using System.Collections.Generic;

public class QueueExample

public static void Main(string[] args)

Queue<string> names = new Queue<string>();

names.Enqueue("Sonoo");

names.Enqueue("Peter");

names.Enqueue("James");

names.Enqueue("Ratan");

names.Enqueue("Irfan");

foreach (string name in names)

Console.WriteLine(name);

Console.WriteLine("Peek element: "+names.Peek());

Console.WriteLine("Dequeue: "+ names.Dequeue());

Console.WriteLine("After Dequeue, Peek element: " + names.Peek());

LinkedList<T>

LinkedList<T> class uses the concept of linked list. It allows us to insert and delete elements fastly. It can
have duplicate elements.It allows us to add and remove element at before or last index.
LinkedList<T> class that stores elements using AddLast() and AddFirst() methods and iterates elements
using for-each loop.

Example :

using System;

using System.Collections.Generic;

public class LinkedListExample

public static void Main(string[] args)

// Create a list of strings

var names = new LinkedList<string>();

names.AddLast("Sonoo Jaiswal");

names.AddLast("Ankit");

names.AddLast("Peter");

names.AddLast("Irfan");

names.AddFirst("John");//added to first index

// Iterate list element using foreach loop

foreach (var name in names)

Console.WriteLine(name);

}
}

Note: Unlike List, you cannot create LinkedList using Collection initializer.

Example 2 :

LinkedList<T> class that stores elements before and after specific node. To get the specific node, we are
calling Find() method.

using System;

using System.Collections.Generic;

public class LinkedListExample

public static void Main(string[] args)

// Create a list of strings

var names = new LinkedList<string>();

names.AddLast("Sonoo");

names.AddLast("Ankit");

names.AddLast("Peter");

names.AddLast("Irfan");

//insert new element before "Peter"

LinkedListNode<String> node=names.Find("Peter");

names.AddBefore(node, "John");

names.AddAfter(node, "Lucy");
// Iterate list element using foreach loop

foreach (var name in names)

Console.WriteLine(name);

Dictionary<TKey, TValue>

Dictionary<TKey, TValue> class uses the concept of hashtable. It stores values on the basis of key. It
contains unique keys only. By the help of key, we can easily search or remove elements.

Dictionary<TKey, TValue> class that stores elements using Add() method and iterates elements using
for-each loop. Here, we are using KeyValuePair class to get key and value.

Example :

using System;

using System.Collections.Generic;

public class DictionaryExample

public static void Main(string[] args)

Dictionary<string, string> names = new Dictionary<string, string>();

names.Add("1","Sonoo");

names.Add("2","Peter");
names.Add("3","James");

names.Add("4","Ratan");

names.Add("5","Irfan");

foreach (KeyValuePair<string, string> kv in names)

Console.WriteLine(kv.Key+" "+kv.Value);

SortedDictionary<TKey, TValue>

SortedDictionary<TKey, TValue> class uses the concept of hashtable. It stores values on the basis of key.
It contains unique keys and maintains ascending order on the basis of key. By the help of key, we can
easily search or remove elements.

SortedDictionary<TKey, TValue> class that stores elements using Add() method and iterates elements
using for-each loop. Here, we are using KeyValuePair class to get key and value.

Example :

using System;

using System.Collections.Generic;

public class SortedDictionaryExample

public static void Main(string[] args)

{
SortedDictionary<string, string> names = new SortedDictionary<string, string>();

names.Add("1","Sonoo");

names.Add("4","Peter");

names.Add("5","James");

names.Add("3","Ratan");

names.Add("2","Irfan");

foreach (KeyValuePair<string, string> kv in names)

Console.WriteLine(kv.Key+" "+kv.Value);

SortedList<TKey, TValue>

SortedList<TKey, TValue> is an array of key/value pairs. It stores values on the basis of key. The
SortedList<TKey, TValue> class contains unique keys and maintains ascending order on the basis of key.
By the help of key, we can easily search or remove elements.

It is like SortedDictionary<TKey, TValue> class.

SortedList<TKey, TValue> class that stores elements using Add() method and iterates elements using for-
each loop. Here, we are using KeyValuePair class to get key and value.

C# SortedList<TKey, TValue> vs SortedDictionary<TKey, TValue> :


SortedList<TKey, TValue> class uses less memory than SortedDictionary<TKey, TValue>. It is
recommended to use SortedList<TKey, TValue> if you have to store and retrieve key/valye pairs.

The SortedDictionary<TKey, TValue> class is faster than SortedList<TKey, TValue> class if you perform
insertion and removal for unsorted data.

Example :

using System;

using System.Collections.Generic;

public class SortedDictionaryExample

public static void Main(string[] args)

SortedList<string, string> names = new SortedList<string, string>();

names.Add("1","Sonoo");

names.Add("4","Peter");

names.Add("5","James");

names.Add("3","Ratan");

names.Add("2","Irfan");

foreach (KeyValuePair<string, string> kv in names)

Console.WriteLine(kv.Key+" "+kv.Value);

}
Generics

Generic is a concept that allows us to define classes and methods with placeholder. C# compiler replaces
these placeholders with specified type at compile time. The concept of generics is used to create general
purpose classes and methods.

To define generic class, we must use angle <> brackets. The angle brackets are used to declare a class or
method as generic type.

Example:

In the following example, we are creating generic class that can be used to deal with any type of data.

using System;

namespace CSharpProgram

class GenericClass<T>

public GenericClass(T msg)

Console.WriteLine(msg);

class Program

static void Main(string[] args)

GenericClass<string> gen = new GenericClass<string> ("This is generic class");

GenericClass<int> genI = new GenericClass<int>(101);

GenericClass<char> getCh = new GenericClass<char>('I');

With Method:
using System;

namespace CSharpProgram

class GenericClass

public void Show<T>(T msg)

Console.WriteLine(msg);

class Program

static void Main(string[] args)

GenericClass genC = new GenericClass();

genC.Show("This is generic method");

genC.Show(101);

genC.Show('I');

Delegates

delegate is a reference to the method. It works like function pointer in C and C++. But it is objected-
oriented, secured and type-safe than function pointer.

For static method, delegate encapsulates method only. But for instance, method, it encapsulates
method and instance both.

The best use of delegate is to use as event.


Internally a delegate declaration defines a class which is the derived class of System. Delegate.

Syntax:

Modifier delegate datatype DelegateName(params )

Example:

using System;

using System.Collections.Generic;

class Program

// define a method that returns sum of two int numbers

static int calculateSum(int x, int y)

return x + y;

// define a delegate

public delegate int myDelegate(int num1, int num2);

static void Main()

// create an instance of delegate by passing method name

myDelegate d = new myDelegate(calculateSum);

// calling calculateSum() using delegate

int result = d(5, 6);

Console.WriteLine(result);

}
}

Advantages:

promote reusability of code and implement flexibility

notify which method to call when an event is triggered

define callback methods

Multicast Delegates:

The multicast delegate is used to point to more than one method at a time. We use += operator to add
methods to delegate.

Example:

using System;

class Program

// method that prints sum of two int numbers

public void sum(int x, int y)

Console.WriteLine("Sum is: " + (x + y));

// method that prints difference of two int numbers

public void difference(int x, int y)

Console.WriteLine("Difference is: " + (x - y));

// define a delegate of int type

public delegate void myDelegate(int num1, int num2);

static void Main()


{

// instance of Program class

Program obj = new Program();

// create an instance of delegate and

// pass sum method as a parameter

myDelegate d = new myDelegate(obj.sum);

// multicast delegate

// calls difference() method

d += obj.difference;

// pass values to two methods i.e sum() and difference()

d(6, 5);

Output:

Sum is: 11

Difference is: 1

Reflection

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

Note

Make sure you add using System; and using System.Reflection; at the top of your .cs file.
Example: Get Type

using System;

public class ReflectionExample

public static void Main()

int a = 10;

Type type = a.GetType();

Console.WriteLine(type);

The output is: System.Int32.

Example 2: Get Assembly

using System;

using System.Reflection;

public class ReflectionExample

public static void Main()

Type t = typeof(System.String);

Console.WriteLine(t.Assembly);

} }

ArrayList

The ArrayList is a collection of objects of same or different types. The size of an ArrayList can be
dynamically increased or decreased as per the requirement. It works like an array but unlike array in
ArrayList items can be dynamically allocated or deallocated, i.e you can add, remove, index, or search
for data in a collection.

Add() - Add single element to ArrayList.


Insert() - Allow inserting a single element at the specific position.

Remove() - Remove single elemet from ArrayList.

RemoveAt() - Remove element from specific postion.

Difference Between Array and ArrayList

Example:
using System;
using System.Collections;

class Program
{
static void Main()
{
ArrayList al = new ArrayList();
al.Add("123");
al.Add(123);
al.Add(123M);
al.Add(1234F);
al.Add(true);

al.Insert(2, false);
al.Remove(true);

al.RemoveAt(4);

string va = al[0].ToString();

foreach (var item in al)


{
Console.WriteLine(item);
}

}
}

TextWriter

C# TextWriter class is an abstract class. It is used to write text or sequential series


of characters into file. It is found in System.IO namespace.

Example :

using System;
using System.IO;
namespace TextWriterExample
{
class Program
{
static void Main(string[] args)
{
using (TextWriter writer = File.CreateText("e:\\f.txt"))
{
writer.WriteLine("Hello C#");
writer.WriteLine("C# File Handling by Veda");
}
Console.WriteLine("Data written successfully...");
}
}
}

TextReader

C# TextReader class is found in System.IO namespace. It represents a reader that can be


used to read text or sequential series of characters.

Example :

using System;
using System.IO;
namespace TextReaderExample
{
class Program
{
static void Main(string[] args)
{
using (TextReader tr = File.OpenText("e:\\f.txt"))
{
Console.WriteLine(tr.ReadToEnd());
}
}
}
}

If need to read only one line:

Example:

using System;
using System.IO;
namespace TextReaderExample
{
class Program
{
static void Main(string[] args)
{
using (TextReader tr = File.OpenText("e:\\f.txt"))
{
Console.WriteLine(tr.ReadLine());
}
}
}
}

Anonymous Functions

Anonymous function is a type of function that does not has name. In other words, we can say that a
function without name is known as anonymous function.

In C#, there are two types of anonymous functions:

Lambda Expressions
Anonymous Methods
Lambda Expressions:

Lambda expression is an anonymous function which we can use to create delegates. We can use lambda
expression to create local functions that can be passed as an argument. It is also helpful to write LINQ
queries.

Syntax :

(input-parameters) => expression

Example :

using System;
namespace LambdaExpressions
{
class Program
{
delegate int Square(int num);
static void Main(string[] args)
{
Square GetSquare = x => x * x;
int j = GetSquare(5);
Console.WriteLine("Square: "+j);
}
}
}

Example with methods :

Note: the anonymous types cannot contain methods.

using System;
namespace AnonymousMethods
{
class Program
{
public delegate void AnonymousFun();
static void Main(string[] args)
{
AnonymousFun fun = delegate () {
Console.WriteLine("This is anonymous function");
};
fun();
} } }

Multithreading is one of the most important concepts in C# that you need to understand as a developer.

Multitasking

our system
example our system will work with chrome , firefox , vs and sql

How Does the Operating System Execute Multiple Applications at a time?

To execute multiple applications (Google Chrome Browser, Microsoft word document, Notepad, VLC
Media Player, Visual Studio, etc) at the same time, the operating system internally makes use of
processes.

What is a Process?

A process is a part of the operating system (or a component under the operating system) which is
responsible for executing the program or application. So, to execute each and every program or
application, there will be a process.

You can see the process which are executing the programs or applications using the Task Manager. Just
right-click on the Taskbar and click on the Task Manager option which will open the Task Manager
window. From that window, just click on the “Processes” button as shown below.

What is Thread?
Generally, a Thread is a lightweight process. In simple words, we can say that a Thread is a unit of a
process that is responsible for executing the application code. So, every program or application has some
logic or code, and to execute that logic or code, Thread comes into the picture.

By default, every process has at least one thread that is responsible for executing the application code
and that thread is called Main Thread. So, every application by default is a single-threaded application.

Name Space :

System.Threading

Example :

using System;
namespace ThreadingDemo
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Welcome to Threding!");
Console.ReadKey();
}
}
}
Thread Class in C#:

If you go to the definition of Thread Class in C#, then you will see that it contains one static property
called CurrentThread which is going to return the instance of the currently executing thread i.e. the
thread which is running your application code

As you can see the CurrentThread static property return type is Thread i.e. it is going to return the
instance of the currently executing thread. Along the same line, there is a non-static property called
Name using which we can set and get the Name of the currently executing thread.

Note: By default, the thread does not have any name. If you want then you can provide any name to the
thread by using the Name property of the Thread class. So, modify the program as shown below where
we are setting the Name property of the thread class as well as printing the Name property.

Example :

using System.Threading;
using System;
namespace ThreadingDemo
{
class Program
{
static void Main(string[] args)
{
Thread t = Thread.CurrentThread;
//By Default, the Thread does not have any name
//if you want then you can provide the name explicitly
t.Name = "Main Thread";
Console.WriteLine("Current Executing Thread Name :" + t.Name);
Console.WriteLine("Current Executing Thread Name :" + Thread.CurrentThread.Name);
Console.Read();
}
}
}

What are the drawbacks of Single-Threaded Applications in .NET Framework?

In a single-threaded application, all the logic or code present in the program will be executed by a single
thread only i.e. the Main thread. For example, if we have three methods in our application and if all these
three methods are going to be called from the Main method. Then the Main thread is only responsible to
execute all these three methods sequentially i.e. one by one. It will execute the first method and once it
completes the execution of the first method then only it executes the second method and so on

Example :

using System;
namespace ThreadingDemo
{
class Program
{
static void Main(string[] args)
{
Method1();
Method2();
Method3();
Console.Read();
}
static void Method1()
{
for (int i = 1; i <= 5; i++)
{
Console.WriteLine("Method1 :" + i);
}
}

static void Method2()


{
for (int i = 1; i <= 5; i++)
{
Console.WriteLine("Method2 :" + i);
}
}
static void Method3()
{
for (int i = 1; i <= 5; i++)
{
Console.WriteLine("Method3 :" + i);
}
}
}
}

Example to Understand the Problem of Single-Threaded Application in C#.

we can hold the program using Thread.Sleep


time will always int millisecondsTimeout

Example :

using System.Threading;
using System;
namespace ThreadingDemo
{
class Program
{
static void Main(string[] args)
{
Method1();
Method2();
Method3();
Console.Read();
}
static void Method1()
{
for (int i = 1; i <= 5; i++)
{
Console.WriteLine("Method1 :" + i);
}
}
static void Method2()
{
for (int i = 1; i <= 5; i++)
{
Console.WriteLine("Method2 :" + i);
if (i == 3)
{
Console.WriteLine("Performing the Database Operation Started");
//Sleep for 10 seconds
Thread.Sleep(10000);
Console.WriteLine("Performing the Database Operation Completed");
}
}
}
static void Method3()
{
for (int i = 1; i <= 5; i++)
{
Console.WriteLine("Method3 :" + i);
}
}
}
}

How to solve the above problem?

using Multithreading we can achive this

What is Multithreading in C#?

If multiple threads are used to execute your application code, then it is called Multithreading.
Multithreading is a mechanism to implement Concurrent Programming where multiple threads operate
simultaneously. Threads are lightweight processes that signify the execution path in a program. Thread
usage increases the efficiency of an application and reduces CPU cycle time wastage. The main advantage
of using Multithreading is the maximum utilization of CPU resources.

Note: The Thread class in C# is a sealed class, so it cannot be inherited.

Example :

using System.Threading;
using System;
namespace ThreadingDemo
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Main Thread Started");
//Creating Threads
Thread t1 = new Thread(Method1)
{
Name = "Thread1"
};
Thread t2 = new Thread(Method2)
{
Name = "Thread2"
};
Thread t3 = new Thread(Method3)
{
Name = "Thread3"
};
//Executing the methods
t1.Start();
t2.Start();
t3.Start();
Console.WriteLine("Main Thread Ended");
Console.Read();
}
static void Method1()
{
Console.WriteLine("Method1 Started using " + Thread.CurrentThread.Name);
for (int i = 1; i <= 5; i++)
{
Console.WriteLine("Method1 :" + i);
}
Console.WriteLine("Method1 Ended using " + Thread.CurrentThread.Name);
}
static void Method2()
{
Console.WriteLine("Method2 Started using " + Thread.CurrentThread.Name);
for (int i = 1; i <= 5; i++)
{
Console.WriteLine("Method2 :" + i);
if (i == 3)
{
Console.WriteLine("Performing the Database Operation Started");
//Sleep for 10 seconds
Thread.Sleep(10000);
Console.WriteLine("Performing the Database Operation Completed");
}
}
Console.WriteLine("Method2 Ended using " + Thread.CurrentThread.Name);
}
static void Method3()
{
Console.WriteLine("Method3 Started using " + Thread.CurrentThread.Name);
for (int i = 1; i <= 5; i++)
{
Console.WriteLine("Method3 :" + i);
}
Console.WriteLine("Method3 Ended using " + Thread.CurrentThread.Name);
}
}
}

Foreground and Background Threads in C#

Foreground Thread in C#:

Foreground threads are those threads that keep running even after the main application exits or quits.
That means if the Main thread leaves the application, then still the foreground threads are running to
complete their assigned task. So, the foreground threads in C# do not care whether the main thread is
alive or not, it completes only when it finishes its assigned work. That means the life of a foreground
thread in C# does not depend upon the main thread. The foreground thread has the ability to prevent the
current application from terminating. The CLR will not shut down the application until all the Foreground
Threads have finished their assigned work. The main thread is a foreground thread.

using System;
using System.Threading;
namespace MultithreadingDemo
{
public class Program
{
static void Main(string[] args)
{
// A thread created here to run Method1 Parallely
Thread thread1 = new Thread(Method1);
Console.WriteLine($"Thread1 is a Background thread: {thread1.IsBackground}");
thread1.Start();
//The control will come here and will exit
//the main thread or main application
Console.WriteLine("Main Thread Exited");
}
// Static method
static void Method1()
{
Console.WriteLine("Method1 Started");
for (int i = 0; i <= 5; i++)
{
Console.WriteLine("Method1 is in Progress!!");
Thread.Sleep(1000);
}
Console.WriteLine("Method1 Exited");
Console.WriteLine("Press any key to Exit.");
Console.ReadKey();
}
}
}

Background Thread in C#:

Background Threads are those threads that will quit if our main application quits. Or in simple words, we
can say that the life of the background thread will depend upon the life of the main thread. In short, if our
main application quits, then the background threads will also quit. Background threads are viewed by the
CLR and if all foreground threads have terminated, then all the background threads are automatically
stopped when the application quits.

Note: By default, when we created a thread in C#, it is a Foreground thread

Example :

using System;
using System.Threading;
namespace MultithreadingDemo
{
public class Program
{
static void Main(string[] args)
{
// A thread created here to run Method1 Parallely
Thread thread1 = new Thread(Method1)
{
//Thread becomes background thread
IsBackground = true
};

Console.WriteLine($"Thread1 is a Background thread: {thread1.IsBackground}");


thread1.Start();
//The control will come here and will exit
//the main thread or main application
Console.WriteLine("Main Thread Exited");
//As the Main thread (i.e. foreground thread exits the application)
//Automatically, the background thread quits the application
}
// Static method
static void Method1()
{
Console.WriteLine("Method1 Started");
for (int i = 0; i <= 5; i++)
{
Console.WriteLine("Method1 is in Progress!!");
Thread.Sleep(1000);
}
Console.WriteLine("Method1 Exited");
Console.WriteLine("Press any key to Exit.");
Console.ReadKey();
}
}
}

Threads Priorities in C#

each and every thread has a priority that determines how often the thread gets access to the CPU

Example :

using System;
using System.Threading;
namespace ThreadStateDemo
{
class Program
{
static void Main(string[] args)
{
Thread thread1 = new Thread(SomeMethod)
{
Name = "Thread 1"
};
//Setting the thread Priority as Normal
thread1.Priority = ThreadPriority.Normal;
Thread thread2 = new Thread(SomeMethod)
{
Name = "Thread 2"
};
//Setting the thread Priority as Lowest
thread2.Priority = ThreadPriority.Lowest;
Thread thread3 = new Thread(SomeMethod)
{
Name = "Thread 3"
};
//Setting the thread Priority as Highest
thread3.Priority = ThreadPriority.Highest;
//Getting the thread Prioroty
Console.WriteLine($"Thread 1 Priority: {thread1.Priority}");
Console.WriteLine($"Thread 2 Priority: {thread2.Priority}");
Console.WriteLine($"Thread 3 Priority: {thread3.Priority}");
thread1.Start();
thread2.Start();
thread3.Start();
Console.ReadKey();
}
public static void SomeMethod()
{
for (int i = 0; i < 3; i++)
{
Console.WriteLine($"Thread Name: {Thread.CurrentThread.Name} Printing {i}");
}
}
}
}

Thread Life Cycle :

A thread in C# has a life cycle, which will start when we create an instance of the Thread class, and the
thread life cycle ends when the task execution of the thread is completed or when the thread is
terminated. A thread in C# at any point in time exists in any one of the following states.

Unstarted (New) State


Runnable State (Ready to Run)
Running
Not Runnable State
Dead State

When we create an instance of a Thread class, it is in an unstarted state.

When we call the start() method, then the thread will move from the unstarted state to the runnable or
ready-to-run state

A thread will enter into the running state, when the thread scheduler selected it to run (out of all the
threads which are ready to run or in the runnable state), only one thread within a process can be
executed at a time

A thread in C# enters into the Not Runnable State in the following scenarios.
When we called the Sleep() method

When the thread completed its task, the thread enters into a dead, terminates, or abort state

Sleep(): This method Suspends the current thread for the specified amount of time.
Join(): This method blocks the calling thread until the thread represented by this instance terminates
while continuing to perform standard COM and SendMessage pumping.
Abort(): This method Raises a System.Threading.ThreadAbortException in the thread on which it is
invoked, to begin the process of terminating the thread. Calling this method usually terminates the
thread.
Suspend(): This method either suspends the thread or if the thread is already suspended, has no effect.
Resume(): This method resumes a thread that has been suspended.
Start(): This method causes the operating system to change the state of the current instance to the
Running state.

Example :

using System;
using System.Threading;
namespace ThreadStateDemo
{
class Program
{
static void Main(string[] args)
{
try
{
// Creating and initializing threads Unstarted state
Thread thread1 = new Thread(SomeMethod);
Console.WriteLine($"Before Start, IsAlive: {thread1.IsAlive}, ThreadState:
{thread1.ThreadState}");
// Running State
thread1.Start();
Console.WriteLine($"After Start(), IsAlive: {thread1.IsAlive}, ThreadState:
{thread1.ThreadState}");
// thread1 is in suspended state
thread1.Suspend();
Console.WriteLine($"After Suspend(), IsAlive: {thread1.IsAlive}, ThreadState:
{thread1.ThreadState}");
// thread1 is resume to running state
thread1.Resume();
Console.WriteLine($"After Resume(), IsAlive: {thread1.IsAlive}, ThreadState:
{thread1.ThreadState}");
// thread1 is in Abort state
//In this case, it will start the termination, IsAlive still gives you as true
thread1.Abort();
Console.WriteLine($"After Abort(), IsAlive: {thread1.IsAlive}, ThreadState:
{thread1.ThreadState}");
//Calling the Start Method on a dead thread will result an Exception
thread1.Start();
}
catch (Exception ex)
{
Console.WriteLine($"Exception Occurred: {ex.Message}");
}

Console.ReadKey();
}
public static void SomeMethod()
{
for (int x = 0; x < 3; x++)
{
Thread.Sleep(1000);
}
Console.WriteLine("SomeMethod Completed...");
}
}
}

What is a Deadlock in C#?

In simple words, we can define a deadlock in C# as a situation where two or more threads are unmoving
or frozen in their execution because they are waiting for each other to finish.

For example, let’s say we have two threads Thread1 and Thread2 and at the same time let’s say we have
two resources Resource1 and Resource2. The Thread1 locked the Resource1 and tried to acquire a lock
on Respurce2. At the same time, Thread2 acquired a lock on Resource2 and tried to acquire a lock on
Resource1.
As you can see in the above image, Thread1 is waiting to acquire a lock on Resource2 which is held by
Thread2. Thread2 also can’t finish its work and release the lock on Resource2 because it is waiting to
acquire a lock on Resource1 which is locked by Thread1, and hence a Deadlock situation occurred.

Example:

namespace DeadLockDemo
{
public class Account
{
public int ID { get; }
private double Balance { get; set;}
public Account(int id, double balance)
{
ID = id;
Balance = balance;
}

public void WithdrawMoney(double amount)


{
Balance -= amount;
}
public void DepositMoney(double amount)
{
Balance += amount;
}
}
}
The above Account class is very straightforward. We created the class with two properties i.e. ID and
Balance. Through the constructor of this class, we are initializing these properties. So, at the time of
Account class instance creation, we need to pass the ID and Balance value. Here we have also created
two methods. The WithdrawMoney method is used for withdrawing the amount while the DepositMoney
method is used for adding the amount.

AccountManager.cs:

Next, create another class file with the name AccountManager.cs and then copy and paste the following
code into it.

using System;
using System.Threading;
namespace DeadLockDemo
{
public class AccountManager
{
private Account FromAccount;
private Account ToAccount;
private double TransferAmount;
public AccountManager(Account AccountFrom, Account AccountTo, double AmountTransfer)
{
FromAccount = AccountFrom;
ToAccount = AccountTo;
TransferAmount = AmountTransfer;
}
public void FundTransfer()
{
Console.WriteLine($"{Thread.CurrentThread.Name} trying to acquire lock on {FromAccount.ID}");
lock (FromAccount)
{
Console.WriteLine($"{Thread.CurrentThread.Name} acquired lock on {FromAccount.ID}");
Console.WriteLine($"{Thread.CurrentThread.Name} Doing Some work");
Thread.Sleep(1000);
Console.WriteLine($"{Thread.CurrentThread.Name} trying to acquire lock on {ToAccount.ID}");
lock (ToAccount)
{
FromAccount.WithdrawMoney(TransferAmount);
ToAccount.DepositMoney(TransferAmount);
}
}
}
}
}

In the above code, we created two Account type variables to hold the FromAccount and ToAccount
details i.e. the Account from where the amount is going to be deducted and the account to whom the
amount is created. We also created another double-type variable i.e. TransferAmount to hold the amount
which is going to be deducted from the FromAccount and credited to the ToAccount. Through the
constructor of this class, we are initializing these variables.

We also created the FundTransfer method which is going to perform the required task. As you can see, it
first acquires a lock on From Account and then does some work. After 1 second it backs and tries to
acquire a lock on To Account.

Modifying the Main Method:

Now modify the Main method of the Program class as shown below. Here, for accountManager1,
Account1001 is the FromAccount and Account1002 is the ToAccount. Similarly, for accountManager2,
Account1002 is the FromAccount and Account1001 is the ToAccount

using System;
using System.Threading;
namespace DeadLockDemo
{
class Program
{
public static void Main()
{
Console.WriteLine("Main Thread Started");
Account Account1001 = new Account(1001, 5000);
Account Account1002 = new Account(1002, 3000);
AccountManager accountManager1 = new AccountManager(Account1001, Account1002, 5000);
Thread thread1 = new Thread(accountManager1.FundTransfer)
{
Name = "Thread1"
};
AccountManager accountManager2 = new AccountManager(Account1002, Account1001, 6000);
Thread thread2 = new Thread(accountManager2.FundTransfer)
{
Name = "Thread2"
};
thread1.Start();
thread2.Start();
thread1.Join();
thread2.Join();
Console.WriteLine("Main Thread Completed");
Console.ReadKey();
}
}
}

Note: For thread1, Account1001 is resource1 and Account1002 is resource2. On the other hand, for
thread2, Account1002 is resource1 and Account1001 is resource2. With this keep in mind run the
application and see deadlock occurred.

The reason for the deadlock is that thread1 acquired an exclusive lock on Account1001 and then do some
processing. Meantime thread2 started and it acquired an exclusive lock on Account1002 and then does
some processing. Then thread1 back and wants to acquire a lock on Account1001 which is already locked
by thread2. Similarly, thread2 is back and wants to acquire a lock on Account1002 which is already locked
by thread1 and hence deadlock.

Regular Expression
In C#, Regular Expression is used for the parsing and validation of the given text to match with the defined
pattern (for example, an email address). The pattern can contain operators, characters literals, or
constructs.

To process the text with the regular Expression in .NET Framework, generally, we used the regular
expression engine. In C#, Regular Expression is shown by the Regex.

Regex Class

Regex class shows the regular expression engine in the .NET Framework. Regex class is used to parse a
large amount of text for finding the specific character pattern. We can use the Regex class for the
extraction, editing, for the replacement, or to delete the text of the substring.

Regex Class method in C#

IsMatch ->We used the IsMatch method for finding out whether the given input string matches the
regular expression pattern or not.

Matches ->Matches method is used to return the text, which matches with the regular expression
pattern.

Replace ->Replace method is used to replace the text, which matches the regular expression pattern.

Split ->We used the Split method for splitting the string into the array of the substring at those
positions, which matches with the regular expression pattern.

Regular Expression Example :

using System;
using System.Text.RegularExpressions;

namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
string email = "support@javatpoint.com";

var result = Regex.IsMatch(email, @"^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$");

Console.Write("Is valid: {0} ", result);


Console.ReadLine();
}
}
}

Regex Replace String Example:

using System;
using System.Text.RegularExpressions;

namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string str = "Hi,welcome@Veda.in";

string result = Regex.Replace(str, "[^a-zA-Z0-9_]+", " ");

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

Console.ReadLine();
}
}
}
Find the Duplicate Words:

using System;
using System.Text.RegularExpressions;

namespace ConsoleApp1
{
class Program1
{
static void Main(string[] args)
{
string str1 = "Welcome To to Veda. Here we can learn C# easily easily way";

MatchCollection collection = Regex.Matches(str1, @"\b(\w+?)\s\1\b", RegexOptions.IgnoreCase);

foreach (Match m in collection)

Console.WriteLine("{0} (duplicates '{1}') at position {2}", m.Value, m.Groups[1].Value, m.Index);


}

Console.ReadLine();
}
}
}

Enumeration types

An enumeration type (or enum type) is a value type defined by a set of named constants of the
underlying integral numeric type. To define an enumeration type, use the enum keyword and specify the
names of enum members:

Note: if you not assign any value it will take default start from zero (0)

Example :

using System;
using System.Text.RegularExpressions;

namespace ConsoleApp1
{
class Program1
{
static void Main(string[] args)
{
int answer = Convert.ToInt32(StatusClass.Active);
Console.WriteLine(StatusClass.Active);
Console.WriteLine(answer);
}
}
}

enum StatusClass
{
Active = 1,
Inactive = 2,
Delete = 3,
Disable = 4,
}
Garbage collection

In the common language runtime (CLR), the garbage collector (GC) serves as an automatic memory
manager. The garbage collector manages the allocation and release of memory for an application.
Therefore, developers working with managed code don't have to write code to perform memory
management tasks. Automatic memory management can eliminate common problems such as forgetting
to free an object and causing a memory leak or attempting to access freed memory for an object that's
already been freed.

Benefits

1. Frees developers from having to manually release memory.


2. Allocates objects on the managed heap efficiently.
3. Reclaims objects that are no longer being used, clears their memory, and keeps the memory available
for future allocations. Managed objects automatically get clean content to start with, so their
constructors don't have to initialize every data field.
4. Provides memory safety by making sure that an object can't use for itself the memory allocated for
another object.

GC works on managed heap, which is nothing but a block of memory to store objects, when garbage
collection process is put in motion, it checks for dead objects and the objects which are no longer used,
then it compacts the space of live object and tries to free more memory.

Basically, heap is managed by different 'Generations', it stores and handles long-lived and short-lived
objects, see the below generations of Heap:

1 -- > 0 Generation (Zero): This generation holds short-lived objects, e.g., Temporary objects. GC initiates
garbage collection process frequently in this generation.

2 -- > 1 Generation (One): This generation is the buffer between short-lived and long-lived objects.

3 -- > 2 Generation (Two): This generation holds long-lived objects like a static and global variable, that
needs to be persisted for a certain amount of time. Objects which are not collected in generation Zero,
are then moved to generation 1, such objects are known as survivors, similarly objects which are not
collected in generation One, are then moved to generation 2 and from there onwards objects remain in
the same generation.

When GC gets triggered?

There are no specific timings for GC to get triggered, GC automatically starts operation on the following
conditions:

1.When virtual memory is running out of space.


2.When allocated memory is suppressed acceptable threshold (when GC found if the survival rate (living
objects) is high, then it increases the threshold allocation).
3.When we call GC.Collect() method explicitly, as GC runs continuously, we actually do not need to call
this method.

What is managed and unmanaged objects/resources?

Managed objects are created, managed and under scope of CLR, pure .NET code managed by runtime,
Anything that lies within .NET scope and under .NET framework classes such as string, int, bool variables
are referred to as managed code.

UnManaged objects are created outside the control of .NET libraries and are not managed by CLR,
example of such unmanaged code is COM objects, file streams, connection objects, Interop objects.
(Basically, third party libraries that are referred in .NET code.)

We can delete those Unmnaged code using following methods

Dispose() and Finalize();

The method dispose( ) is invoked by the user.


The method finalize( ) is invoked by the garbage collector.
Method dispose( ) is used to free unmanaged resources whenever it is invoked.
Method finalize( ) is used to free unmanaged resources before the object is destroyed.

Differences Between dispose() and finalize()

1. The method dispose() is defined in an interface IDisposable. On the other hand, the method finalize() is
defined in the class object.

2. The method dispose() has to be manually invoked inside the code by a programmer, while the method
finalize is automatically invoked by the garbage collector before it destroys the object.

3. The method dispose could be invoked anytime, whereas the method finalize is invoked by the garbage
collector when it finds that that object has not been referenced for a long time.

4. The method dispose() is implemented in a class after implementing the interface IDisposable. The
method finalize() has to be implemented only for unmanaged resources because the managed resources
are automatically freed by the garbage collector.

5. The access specifier of the method dispose() is public as it is defined in the interface IDisposable and it
would be implemented by the class that implements this interface hence, it should be public. On the
other hand, the method finalize() has protected access specifier so that it should not be accessible to any
member outside the class.
6. The method dispose() is fast and frees the object instantly hence, it does not affects the performance
cost. The method finalize() is slower and does not free the resources held by the object instantly.

It is suggested to use method dispose() over the method finalize() as it is faster than finalize. Also, it could
be called any time, when needed

Example for Dispose: Close the Connection using Dispose Method

You might also like