CSharp File
CSharp File
.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#?
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.
CTS provides guidelines for declaring, using, and managing data types at runtime. It offers cross-
language communication.
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:
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:
These are integer and floating point based. Some examples of value data types are int, char,
float etc.
These data types contain a reference to the variables and not the actual data. Some build in
reference types is object, dynamic and string.
This store the memory address of another data type and the data can be accessed using
pointers.
bool
byte
char
decimal
double
enum
float
int
long
sbyte
short
struct
uint
ulong
ushort
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.
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 −
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;
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 −
ToBoolean
ToByte
ToChar
ToDecimal
ToDouble
ToInt16
ToInt32
ToInt64
ToSbyte
ToSingle
ToString
ToType
ToUInt16
ToUInt64
Example:
using System;
namespace TypeConversionApplication {
class StringConversion {
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 −
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 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
&& Called Logical AND operator. If both the operands are non (A && B) is
zero then condition becomes true. false.
Assignment Operators
There are following assignment operators supported by C# −
Miscellaneous Operators
There are few other important operators including sizeof, typeof and ? : supported by C#.
?: If Condition is true ?
Conditional Expression Then value X : Otherwise
value Y
Boxing
The process of converting from a value type to reference type is called boxing
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
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;
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.
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.
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;
}
}
}
}
using System;
namespace _1st_program
{
class Program
{
static void Main(string[] args)
{
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
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:
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
// reverse numbers
// Nested Loop
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
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
i++;
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;
int i;
Goto
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!");
Logical Programs:
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.
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;
Advantages:
Disadvantages:
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.
Examples:
using System;
namespace AccessArray {
class Program {
// create an array
Console.ReadLine();
using System;
namespace ChangeArray {
class Program {
// create an array
numbers[0] = 11;
Console.ReadLine();
using System;
namespace AccessArrayFor {
class Program {
Console.ReadLine();
Here, the Length property of the array gives the size of the array.
------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------
Multidimensional Array
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#
int[ , ] x = { { 1, 2 ,3}, { 3, 4, 5 } };
// a 2D array
int[ , ] x = { { 1, 2 ,3}, { 3, 4, 5 } };
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 {
// old element
numbers[0, 0] = 222;
// new element
}
}
out put :
using System;
namespace MultiDArray {
class Program {
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,
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.
[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,
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
};
We can access the elements of the jagged array using the index number. For example,
jaggedArray[1][0];
jaggedArray[1][1];
jaggedArray[0][1];
using System;
namespace JaggedArray {
class Program {
int[ ][ ] jaggedArray = {
Console.ReadLine();
Output
jaggedArray[1][0]: 2
jaggedArray[1][1]: 4
jaggedArray[0][2]: 5
In C#, we can use loops to iterate through each element of the jagged array. For example,
using System;
namespace JaggedArray {
class Program {
jaggedArray[0][0] = 1;
jaggedArray[0][1] = 3;
jaggedArray[0][2] = 5;
jaggedArray[1][0] = 2;
jaggedArray[1][1] = 2;
}
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,
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
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.
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
{
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;
Note:
Difference
Object Class
C# is an object-oriented program. In object-oriented programming (OOP), we solve complex problems
by dividing them into objects.
create a class
Class
class ClassName {
Note: In C#, fields and methods inside a class are called members of a class.
C# Objects
Suppose, we have a class Veda. StudentName and StudentNumber are the objects of class
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;}
}
vda.StudentName = "Raju";
Console.WriteLine(vda.StudentName);
Console.ReadLine();
using System;
namespace ClassObject {
class Employee {
string department;
sheeran.department = "Development";
Console.ReadLine();
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:
Example
Functions
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.
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
Console.WriteLine("Hello World");
//call method
p1.display();
Console.ReadLine();
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() {
...
int addNumbers() {
...
return sum;
using System;
namespace Method {
class Program {
// method declaration
return sum;
// call method
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:
//code
}
If a method is created with parameters, we need to pass the corresponding values(arguments) while
calling 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 {
class Program {
student1.print();
Console.ReadLine();
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 {
class Program
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 {
class Program {
Console.ReadLine();
Now, let's try to access the protected member from a derived class.
using System;
namespace MyApplication {
class Student {
// derived class
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
class Program
Console.ReadLine();
using System;
namespace Assembly1 {
class Program {
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 {
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 {
class Program {
Console.WriteLine(greet.msg);
Console.ReadLine();
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 {
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 {
Console.Write(student.name);
Console.ReadLine();
Scope of Variables
A variable scope refers to the availability of variables in certain parts of the code.
when we declare a variable inside a class, the variable can be accessed within the class.
When we declare a variable inside a method, the variable cannot be accessed outside of the method.
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
{
Console.ReadLine();
}
}
Constructor
A constructor is similar to a method that is invoked when an object of the class is created.
class Student
Student ()
//code
}
Student () is the Constructor
Call a constructor:
new Student();
Types of Constructors
1. Parameterless Constructor
2. Parameterized Constructor
3. Default Constructor
1. Parameterless Constructor
Example:
using System;
namespace Constructor {
class Car {
// parameterless constructor
Car()
Console.WriteLine("Car Constructor");
// call constructor
new Car();
Console.ReadLine();
2. Parameterized Constructor
Example:
using System;
namespace Constructor
class Car
string brand;
int price;
// parameterized constructor
Car(string theBrand, int thePrice)
brand = theBrand;
price = thePrice;
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.
C# automatically creates a default constructor. The default constructor initializes any uninitialized
variable with the default value.
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;
// copy constructor
Car(Car c1)
brand = c1.brand;
// call constructor
Console.ReadLine();
Explanation of Example:
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.
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 {
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");
Console.ReadLine();
Explanation of Example:
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
Example:
using System;
namespace ThisKeyword {
class Test {
int num;
Test(int num) {
this.num = num;
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.
using System;
namespace ThisKeyword {
class Test {
int num;
Test(int num) {
num = 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.
namespace ThisKeyword {
class Test {
int num;
Test(int num) {
this.num = 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
class Program {
Console.ReadLine();
Instance Variables
every object of a class will have its own copy of instance variables.
class Student {
// instance variable
class Program {
using System;
namespace StaticKeyword {
class Student {
class Program {
s1.studentName = "Ram";
s2.studentName = "Shyam";
Console.ReadLine();
s1.studentName / s2.studentName - calls the non-static variable using objects s1 and s2 respectively
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:
Example:
class Test {
class Program {
Test.display();
using System;
namespace StaticKeyword {
class Test {
Console.WriteLine("Static method");
class Program {
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.
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 {
Console.WriteLine("Static method");
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:
Notice the field and method of the static class are also static because we can only have static members
inside the static class.
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 {
Console.WriteLine("Static method");
Console.WriteLine(age);
display();
Console.ReadLine();
Strings
Methods Description
Replace() replaces the specified old character with the specified new character
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
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.
* Provide public setter and getter methods to modify and view the variables values.
ex:
class Account
if(amount<0 )
else
accountBalance = amount;
}
accountBalance = amount;
class Program
MyAccount.SetBalance(100);
MyAccount.GetBalance();
Console.ReadLine();
Advantages:
• Specification of the accessibility of each of the members of a class to the code outside the class.
• 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.
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 method
// 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:
using System;
namespace Tutlane
public class A
{
Console.WriteLine("Name: {0}", Name);
public class B: A
public class C: B
class Program
C c = new C();
c.Location = "Hyderabad";
c.Age = 32;
c.GetName();
c.GetLocation();
c.GetAge();
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).
Syntax :
interface Operators{
void Add();
interface starts with I so that we can identify it just by seeing its name.
Example :
using System;
namespace CsharpInterface
interface Operators
int result = a + b;
Console.WriteLine(result);
class Program
addmethod.Add(100, 200);
Multiple Inheritence
using System;
namespace CsharpInterface
interface AddOperators
interface SubOperators
{
public void Add(int a, int b)
int result = a + b;
Console.WriteLine(result);
int result = a - b;
Console.WriteLine(result);
class Program
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.
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.
using System;
return a + b;
return a + b + c;
Console.WriteLine(Cal.add(12, 23));
using System;
return a + b;
return a + b;
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;
Console.WriteLine("Veda");
{
Console.WriteLine("veda institute...");
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;
{
public void eat() { Console.WriteLine("eating..."); }
d.eat();
d.bark();
Example on Method:
using System;
Console.WriteLine("Veda");
Console.WriteLine("veda institute...");
Console.WriteLine("veda institute...");
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:
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;
{
Console.WriteLine("Veda");
Console.WriteLine("veda institute...");
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.
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.
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;
Console.WriteLine(base.color);
Console.WriteLine(color);
{
Dog d = new Dog();
d.showColor();
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;
Console.WriteLine("eating...");
base.eat();
Console.WriteLine("eating bread...");
d.eat();
Whenever you inherit the base class, base class constructor is internally invoked. Let's see the example
of calling base constructor.
using System;
public Animal(){
Console.WriteLine("animal...");
public Dog()
Console.WriteLine("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;
}
class GFG
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
// Derived Class
public class My_Member : My_Family {
base.member();
class GFG {
// Main method
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
System.NullReferenceException
System.InvalidCastException
System.IO.IOException
System.FieldAccessException
try
catch
finally, and
throw
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;
try
int a = 10;
int b = 0;
int x = a / b;
Example 2:
using System;
namespace ErrorHandlingApplication
class DivNumbers
int result;
DivNumbers()
result = 0;
try
catch (DivideByZeroException e)
finally
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;
: base(message)
}
}
try
validate(12);
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
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.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
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:
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
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;
names.Add("Sonoo Jaiswal");
names.Add("Ankit");
names.Add("Peter");
names.Add("Irfan");
Console.WriteLine(name);
Example 2:
using System;
using System.Collections.Generic;
public class ListExample
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;
names.Add("Sonoo");
names.Add("Ankit");
names.Add("Peter");
names.Add("Irfan");
Console.WriteLine(name);
Example :
using System;
using System.Collections.Generic;
{
public static void Main(string[] args)
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 static void Main(string[] args)
names.Add("Sonoo");
names.Add("Ankit");
names.Add("Peter");
names.Add("Irfan");
Console.WriteLine(name);
Example:
using System;
using System.Collections.Generic;
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;
names.Push("Sonoo");
names.Push("Peter");
names.Push("James");
names.Push("Ratan");
names.Push("Irfan");
Console.WriteLine(name);
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;
names.Enqueue("Sonoo");
names.Enqueue("Peter");
names.Enqueue("James");
names.Enqueue("Ratan");
names.Enqueue("Irfan");
Console.WriteLine(name);
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;
names.AddLast("Sonoo Jaiswal");
names.AddLast("Ankit");
names.AddLast("Peter");
names.AddLast("Irfan");
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;
names.AddLast("Sonoo");
names.AddLast("Ankit");
names.AddLast("Peter");
names.AddLast("Irfan");
LinkedListNode<String> node=names.Find("Peter");
names.AddBefore(node, "John");
names.AddAfter(node, "Lucy");
// Iterate list element using foreach loop
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;
names.Add("1","Sonoo");
names.Add("2","Peter");
names.Add("3","James");
names.Add("4","Ratan");
names.Add("5","Irfan");
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;
{
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");
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.
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.
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;
names.Add("1","Sonoo");
names.Add("4","Peter");
names.Add("5","James");
names.Add("3","Ratan");
names.Add("2","Irfan");
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>
Console.WriteLine(msg);
class Program
With Method:
using System;
namespace CSharpProgram
class GenericClass
Console.WriteLine(msg);
class Program
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.
Syntax:
Example:
using System;
using System.Collections.Generic;
class Program
return x + y;
// define a delegate
Console.WriteLine(result);
}
}
Advantages:
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
// multicast delegate
d += obj.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;
int a = 10;
Console.WriteLine(type);
using System;
using System.Reflection;
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.
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();
}
}
TextWriter
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
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());
}
}
}
}
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.
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 :
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);
}
}
}
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
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();
}
}
}
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);
}
}
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);
}
}
}
}
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.
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 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 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.
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
};
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}");
}
}
}
}
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.
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...");
}
}
}
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;
}
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.
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.
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.
using System;
using System.Text.RegularExpressions;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
string email = "support@javatpoint.com";
using System;
using System.Text.RegularExpressions;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string str = "Hi,welcome@Veda.in";
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";
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
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.
There are no specific timings for GC to get triggered, GC automatically starts operation on the following
conditions:
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.)
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