.NET
.NET doesn't have a full form or definition. It is a software development framework created by Microsoft.
Used to create various types of applications like mobile, desktop, web and etc. It supporting over 60 programming languages.
It's a language-independent. with Visual Studio as the IDE for development.
Order of Compilation and execution process
Microsoft Intermediate Language (MSIL):
MSIL is a low-level set of instructions created by .NET compilers, like the C# compiler. It translates your C# code but needs another step by the CLR to run on your computer. It handles tasks like Arithmetic Operations, Logical Operations, Data Movement, Control Flow, Method Invocation, Object Creation, Object Manipulation, Exception Handling, and Type Conversion.
It acts as a middle step between the source code and machine code, making the code platform-independent. It serves as a common language for all .NET languages and includes metadata with details about the types, members, and references in the code.
Various types of operations:
Arithmetic Operations: These instructions perform basic mathematical operations. Example instructions include
add
(addition),sub
(subtraction),mul
(multiplication), anddiv
(division).Logical Operations: These instructions handle logical operations used in conditions and bitwise operations. Example instructions include
and
(logical AND),or
(logical OR),xor
(logical XOR), andnot
(logical NOT).Data Movement: These instructions are used to move data between different locations in memory. Example instructions include
ldloc
(load local variable),stloc
(store local variable),ldarg
(load argument), andstarg
(store argument).Control Flow: These instructions control the flow of execution in the program, such as jumping to different parts of code based on conditions. Example instructions include
br
(branch),beq
(branch if equal),bne
(branch if not equal),brtrue
(branch if true), andbrfalse
(branch if false).Method Invocation: These instructions are used to call methods and handle method returns. Example instructions include
call
(call method),callvirt
(call virtual method), andret
(return from method).Object Creation and Manipulation: These instructions manage the creation and manipulation of objects and arrays. Example instructions include
newobj
(create new object),ldfld
(load field),stfld
(store field),ldelem
(load array element), andstelem
(store array element).Exception Handling: These instructions deal with exceptions and error handling. Example instructions include
throw
(throw exception),catch
(catch exception), andfinally
(finally block).Type Conversion: These instructions convert data from one type to another. Example instructions include
conv.i4
(convert to int32) andconv.r8
(convert to double).
Common Language Runtime (CLR):
Definition: The CLR is a part of the .NET framework that manages the execution of .NET programs. The CLR helps .NET programs run on different operating systems like Windows, Linux, and macOS.
In other words, the CLR is like a manager the intermediate code (MSIL) takes generated by .NET compilers and converts it into machine code that your computer can execute.
Role: Turns MSIL into machine code, manages memory, handles security, and deals with errors.
Characteristics:
Execution Environment: Provides the environment where .NET applications run.
Service: Includes garbage collection, error handling, and security features.
Cross-Language Integration: Allows code written in different .NET languages to work together.
Platform Independence:
- The CLR allows .NET programs to work on different operating systems without changing the code.
Implementations:
.NET Framework: Works mainly on Windows.
.NET Core: Works on Windows, Linux, and macOS.
.NET 5+: Combines features of .NET Core and .NET Framework and works on multiple operating systems.
How It Works:
When you write and compile your .NET code, it turns into MSIL (Microsoft Intermediate Language).
The CLR then converts this MSIL into machine code that the computer's hardware can run, no matter what operating system it uses.
The CLR performs several important tasks and includes key components such as:
CLS (Common Language Specification):
A set of rules that makes sure different .NET languages can work together. It ensures that code written in one language can be used in another.
CTS (Common Type System):
A standard that defines how data types are used and managed in .NET. It ensures that different .NET languages can share and use data types correctly.
GC (Garbage Collection):
A system that automatically frees up memory that is no longer needed by your program. This helps prevent memory leaks and keeps your program running smoothly.
JIT (Just-In-Time Compilation):
A process that converts MSIL code into machine code just before it runs. This makes sure your program runs efficiently on different hardware.
Just-In-Time (JIT) Compiler:
The JIT compiler, part of the CLR, converts MSIL into machine code just before execution, optimizing
Characteristics:
On-Demand Compilation: Compiles MSIL to machine code at runtime, rather than beforehand.
Performance Optimization: Makes the code run faster by optimizing it for the specific hardware.
Types of JIT: There are different strategies (like standard JIT, pre-JIT, and EconoJIT) to balance startup time and performance.
Native & machin code:
What is native code and machin code?
Native code (understand by OS): Native code is the code that is compiled to run on a specific processor and operating system without the need for further translation or interpretation. Executed directly by the operating system and hardware . Generated by compilers from high-level programming languages and can contain platform-specific optimizations. Format of native code is can include metadata, headers, and other information in addition to the actual machine code (e.g., executables, libraries).
Machine code(understand by CPU): Machine code is the simplest form of a program that the computer's CPU can run directly. It is made up of binary instructions that the processor can understand. Executed directly by the CPU . Directly generated from assembly language by an assembler or as an intermediate step by a compiler. Format of machine code is pure binary instructions understood by the CPU.
In short, native code is the compiled code that is ready to run on a specific platform, while machine code is the binary instructions that the CPU runs directly. Native code includes machine code and platform-specific details, making it efficient for a particular system.
Dll & Exe file:
A .dll (Dynamic Link Library) file contains code and data that can be used by multiple programs simultaneously.
And the .exe (Executable) file is a standalone application that can be directly run by the operating system.
But the .dll file cannot be directly run, it must be called by an executable (.exe) or another program that uses its functions.
The execution process you outlined
Source Code (.cs)
Compilation
MSIL (in .dll or .exe)
Loading by CLR (with OS support)
JIT Compilation to Native Code (with OS support)
Execution by CPU (managed by OS with CLR services)
+------------------+ +-------------------+ +-----------------+ +---------------+
| Source Code (.cs)| -----> | Compilation to | ----->| Assembly (.dll | -----> | Execution by |
| | | MSIL | | or .exe) | | CLR |
| (C# Code) | | (.NET Compiler) | | | | |
+------------------+ +-------------------+ +-----------------+ +---------------+
|
V
+-----------------------------------------------------------------------------------------+
| Common Language Runtime (CLR) |
| +--------------------+ +---------------------+ +-------------------------+ |
| | Just-In-Time | | Garbage | | Execution Environment | |
| | Compilation | | Collection | | Services (Security, | |
| | (Converts MSIL to | | (Automatic Memory | | Exception Handling) | |
| | Native Code) | | Management) | | | |
| +--------------------+ +---------------------+ +-------------------------+ |
+-----------------------------------------------------------------------------------------+
|
V
+-------------------------+
| Operating System |
| (Memory Management, |
| Process Scheduling, |
| I/O Operations, etc.) |
+-------------------------+
|
V
+-------------------------+
| CPU |
| (Executes Native |
| Code) |
+-------------------------+
Source Code (.cs): You write your C# code in files with the
.cs
extension.Compilation to MSIL (Microsoft Intermediate Language): The C# compiler (
csc.exe
) compiles the.cs
files into an assembly, which is either a.dll
or.exe
file containing MSIL, a low-level, platform-independent set of instructions.Assembly (.dll or .exe): The resulting assembly contains the compiled MSIL code and metadata describing the types, members, and references in the code.
Loading and JIT Compilation by the CLR (Common Language Runtime): When you run the application, the operating system loads the CLR into memory, which then loads the assembly and uses the JIT compiler to translate the MSIL code into native machine code specific to the system's processor architecture.
Execution by the CPU: The CPU directly executes the native machine code within the context provided by the operating system, which handles memory, process scheduling, I/O operations, and other essential services.
Execution Environment and Services Provided by the CLR: The CLR offers services like garbage collection, exception handling, and security checks during execution, relying on the operating system for low-level tasks such as memory management, file access, and network communication.
Explanation of the Role of the Operating System
Memory Management: The OS allocates memory for the CLR and the application.
Process Management: The OS manages the execution of the application process.
I/O Operations: The OS handles input and output operations, such as file access and network communication.
System Calls: The CLR and the application make system calls to the OS for various low-level operations.
Beginner Level
What is C#?:
C#.NET (C-Sharp
) bellong from C++ background or you say (C# is a extension of C++ language). But C++ only use for build desktop application and (C-Sharp
) use to build any type of application.
C# is an object-oriented, modern, general-purpose, type-safe language with a rich standard library and cross-platform capabilities, making it effectively platform-independent.
C# is a Part of the .NET framework or run on .NET Framework.
The 1st version was released in year 2002 by Anders Hejlsberg from Microsoft.
C# is case sensitive language.
C# used for Mobile applications, Desktop applications, Web applications, Web services, Web sites, Games, VR, Database applications, And much, much more!
Basic Syntax and Structure:
Example of 'Hello World' program.
using System;
namespace MyApplication
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello");
}
}
}
using is a keyword which used to import namespace or liberaries. All the class define under the namespacesse's like in their System is namespace.
Namespace like a logical container (logical container
mins generaly we group the item's it mins a grouping of files contain by folder and the folder is logical container
because file having size and main containe that way we say physical
but the folder in Operating System not having any size thay way we say logical
).
In programming language
basicaly namespace
is also a logiacal container
because it's contain classe's
or a group of classe's is called namespace
.
Namespace is a collection of related class and interfaces.
Bydefault when we create the project the project name is the namespace, you can change also, in this exaple MyApplication is a project name.
class Program: This line mins when we create the project automaticaly one predefine file is created in project and the file name is Program.cs, thats way bydefault one class Program
create and name is same as a file name .
class Program
it mining i create a class name is Program.
System is a root namespace in C#, in this namespacesse's more than 100 of class containe and by using this using System
we consume all classe's.
namespace
is a keyword which is uded to create our own namespace.
Main
is the Method
which is the entry point
of C# program. You cannot make more then one Main
method in one project's.
Namespace
contain class & class contain method
and method contain code(source-code).
static
: The static
keyword in the context of the Main
method means that this method belongs to the class itself rather than an instance of the class. This means you can call the Main
method without creating an instance of the Program
class.
Main
Method: The Main
method is the entry point of a C# application. It's where the program starts execution. Since it's static
, it can be called by the runtime without having to instantiate the Program
class.
string[] args
is called as command line arguments.
Let's discuss Solutin explorare.
-
This is
Solutin explorare
, Why we say solutin explorare because it's root elements. Also IDE say Solution explprer. To openSolutin explorare
pressctrl + alt + L
. Under
Solutin explorare
one solution is available and the name isLearn
. AndLearn solutin
contain one project and its name isLearn
. You can add multiple project's inLearn Solution
.And the project contain one class the name is
Program
in sideProgram.cs
file.Solution is the collection of Project -> Project is a collection of item's (item's mins lot of things available like classe's, structure, enum, interfasess, windows form's, web form's and etc).
Console.WriteLine("Hello");
use to print the statment's,Console
isclass
whic come fromSystem namespace
.To create
class
under theproject
then you need to addnew item
(all the things which is in project callednew item
) then write click onProject
and click onadd
nextnew item
,You change the code inside of MyClass like that to run it.
using System; namespace Learn { internal class MyClass //It's also a main class because of inside that Main method available. { static void Main() { Console.WriteLine("My Second Class !."); } } }
But if you want to run this class it give you error, Because we cannot told the Visual Stdio which main class i want to execute, thats way i want to told the visual stdio to run MyClass, Then follow this stape.
Double click on
Properties
which in your project.Go to Startup object and next sellect your class.
Run it.
If You want to run any Class you can run it but one thing's are mandatory in side of class Main methid is mandatory.
Data Types
In C-sharp three types of data types.
Value types (int, float, char, double, Byte).
Refrence type (String, array, Object).
Pointer type (int*, char*).
Pointer type is not recommended because it directly interacts with the address of the value.
C# Data Types
|
|-- Value Types
| |-- Primitive Data Types
| | |-- Integral Types (byte, sbyte, short, ushort, int, uint, long, ulong, char)
| | |-- Floating-Point Types (float, double)
| | |-- Decimal Type (decimal)
| | |-- Boolean Type (bool)
| |
| |-- Non-Primitive Value Types
| | |-- Structs (custom structs, DateTime, TimeSpan)
| | |-- Enums (custom enums)
|
|-- Reference Types (Non-Primitive Types)
| |-- Classes (custom classes, String)
| |-- Interfaces (custom interfaces)
| |-- Arrays (int[], int[,], int[][])
| |-- Delegates (custom delegates)
| |-- Strings (string)
|
|-- Pointer Types (int*, char*)
Variable and Constants:
int number = 10;
const double PI = 3.14;
int x = 5, y = 6, z = 50;
int x, y, z; x=y=z=50;
Comments:
Single-line (
//
).Multi-line (
/*...*/
).
Value Types vs. Reference Types:
Value Types (e.g., int
, float
, struct
): The actual value is stored directly on the stack when they are local variables. Each variable of a value type has its own copy of the data.
Reference Types (e.g., class
,objects
, array
, string
,delegate
): The reference (pointer) to the data is stored on the stack if it's a local variable, but the actual data is stored on the heap. Variables of reference types share the same data by holding references to the same memory location.
Local variables are variables that are declared within a method, constructor, or block of code (such as within a loop or conditional statement). They are temporary and exist only during the execution of the method or block of code in which they are declared. Once the method or block completes execution, the local variables are destroyed and their memory is released.
If you want to learn more about Stack and Heap Memory, click here:
Type Casting:
One data type to another called Type Casting.
Two types of type casting.
Implicit Casting (Automatic)
Performed automatically by the C# compiler when there is no risk of data loss.
Example:
int num = 123; long bigNum = num; float smallNum = 12.34F; double largeNum = smallNum;
Explicit Casting (Manual)
convert one data type to another by manually.
Example:
//Double to int: double num = 123.45; int intNum = (int)num; //Long to int: long bigNum = 123456789; int smallNum = (int)bigNum; //String to int: string str = "123"; Convert.ToInt32(str); //String to double: string str = "123.45"; Convert.ToDouble(str); //Int to string: int myInt = 10; Convert.ToString(myInt);
This are the all conversion methods:-
Convert.ToBoolean()
,Convert.ToDouble()
,Convert.ToString()
,Convert.ToInt32()
orint.Parse()
,(int)
, use to convert only double to int.double doubleValue = 3.7; int intResult = (int)doubleValue; // intResult will be 3 (truncation)
Convert.ToInt64()
orlong.Parse()
,string longStr = "9876543210"; long longValue = Convert.ToInt64(longStr); // longValue will be 9876543210
(long)
, Similar to(int)
, but for long integers (64-bit).int intValue = 42; long longResult = (long)intValue; // longResult will be 42
(char)
, Converts an integer value to Unicode(ASCI) character.int charCode = 65; // ASCII code for 'A' char character = (char)charCode; // character will be 'A'
(float) and (double)
, Convert between floating-point types (single-precision and double-precision)..float floatValue = 3.14f; double doubleValue = (double)floatValue; // doubleValue will be 3.14
User Input:
By using
Console.ReadLine()
to get user Input.Example:
using System; class HelloWorld { static void Main() { string userName; userName = Console.ReadLine(); Console.WriteLine("Hello "+ userName+"!"); } }
Operators:
Arithmetic Operators: (
+
,-
,*
,/
,%
,++
,--
);Assignment Operators: (
=
,+=
,-=
,*=
,/=
,%=
,&=
,!=
,|=
,^=
,>>=
,<<=
);Comparison Operators: (
==
,!=
,>
,<
,>=
,<=
);Logical Operators: (
&&
,||
,!
);Example of
&=
,|=
,^=
,>>=
and<<=
:&=
(Bitwise AND Assignment):- AND operators mins if both are true then true(1) another wize false(0).
int a = 6; // binary of 6 is : 0110
int b = 3; // binary of 3 is : 0011
a &= b; // binary result is : 0010 which is 2 binary
Console.WriteLine(a); //Output : 2
|=
(Bitwise OR Assignmenr):- OR operators mins if any one are true(1) then true another wize false(0).
int a = 6; // binary of 6 is : 0110
int b = 3; // binary of 3 is : 0011
a |= b; // binary result is : 0111 which is 7 binary
Console.WriteLine(a); //Output : 7
^=
(Bitwise XOR Assignment):- XOR operators mins if both are opposit diffrent's then true(1) another wize false(0).
int a = 6; // binary of 6 is : 0110
int b = 3; // binary of 3 is : 0011
a ^= b; // binary result is : 0101 which is 5 binary
Console.WriteLine(a); //Output : 5
>>=
(Right Shift Assignment):- First convert into binary, Then remove certain number of digits from right side and add the same number of zero(0) in left side.
int a = 16; // 16 in binary:00010000
a >>= 2; // Shift right by 2 positions: 00000100
Console.WriteLine(a); //Output : 4
<<=
(Left Shift Assignment):- First convert into binary, Then remove certain number of digits from left side and add the same number of zero(0) in right side.
int a = 4; // 16 in binary:00000100
a <<= 2; // Shift right by 2 positions: 00010000
Console.WriteLine(a); //Output : 16
int a = 4; // 16 in binary:00000100
a <<= 3; // Shift right by 2 positions: 00000000
Console.WriteLine(a); //Output : 0
Math:
Math.Max(5, 10); //Out: 10
Use to find highest value bitween 2 value.Math.Min(5, 10); //Out: 5
Use to find lowest value bitween 2 value.Math.Sqrt(64); //Out: 8
Use to find square root of value.Math.Abs(-4.7); //Out: 4.7
Use to return absolute value.Math.Round(9.99); //Out: 10
Use to rounds the nearest whole number.
Strings:
String are used for storing text.
String contain collection of characters which is surrounded by doubele quotes.
Example:
string greeting = "Hello Mritunjay Kumar!";
.Find length of string:
Console.WriteLine(greeting.Length);
.Methods:
ToUpper():
Console.WriteLine(greeting.ToUpper());
.ToLower():
Console.WriteLine(greeting.ToLower());
.
Concatenation:
Using Operator (
+
):string firstName = "Mritunjay"; string lastName = " Kumar"; Console.WriteLine(firstName+lastName);
Using
string.Concat()
:string firstName = "Mritunjay"; string lastName = " Kumar"; Console.WriteLine(string.Concat(firstName,lastName));
Example:
Console.WriteLine(5 + 2); //Output: 7 Console.WriteLine('5' + '5'); //Output: 52 Console.WriteLine("5" + "2"); //Output: 52 Console.WriteLine(true + true); //Output: Error Console.WriteLine(String.Concat(5, 2)); //Output: 52 Console.WriteLine(String.Concat('5', '2')); //Output: 52 Console.WriteLine(String.Concat("5", "2")); //Output: 52 Console.WriteLine(String.Concat(true, true)); //Output: TrueTrue
String Interpolation: (Another method of concatenation by using
$
symbole)string firstName = "Mritunjay"; string lastName = "Kumar"; Console.WriteLine($"My full name is: {firstName} {lastName}"); //Output: My full name is: Mritunjay Kumar
Access Strings:
string firstName = "Mritunjay Kumar"; Console.WriteLine(firstName[0]); //Output: M Console.WriteLine(firstName.IndexOf('i')); //Output: 2 Console.WriteLine(firstName.IndexOf('e')); //Output: -1 Console.WriteLine(firstName.IndexOf('M')); //Output: 0 Console.WriteLine(firstName.IndexOf('m')); //Output: -1 Console.WriteLine(firstName.IndexOf('y')); //Output: 2 Console.WriteLine(firstName.IndexOf('x')); //Output: -1 Console.WriteLine(firstName.IndexOf(' ')); //Output: 9 Console.WriteLine(firstName.IndexOf('K')); //Output: 10 int a = firstName.IndexOf('K'); //a = 10 Console.WriteLine(firstName.Substring(a)); //Output: Kumar
- If multiple same character is in there then return 1st character index.
string firstName = "Mritunjay Kumar Mehata";
Console.WriteLine(firstName.IndexOf(' ')); //Output: 9
Console.WriteLine(firstName.IndexOf('M')); //Output: 9
Special Characters:
string txt = "My name is "Mritunjay Kumar";
It's wrong.
string txt = "My name is \"Mritunjay Kumar";
it's correct.
Here's a table that provides basic syntax for working with strings in C#:
Operation | Syntax | Example |
Single quote (') in a string | Use escape sequence \' | string s = "It\'s a test."; |
Double quote (") in a string | Use escape sequence \" | string s = "He said, \"Hello!\""; |
Backslash () in a string | Use escape sequence \\ | string s = "This is a backslash: \\"; |
Newline in a string | Use escape sequence \n | string s = "First line\nSecond line"; |
Tab in a string | Use escape sequence \t | string s = "Column1\tColumn2"; |
Unicode character | Use escape sequence \u followed by 4-digit hex code | string s = "Unicode: \u263A"; |
Verbatim string literal | Use @ before the string | string s = @"C:\Program Files"; |
Interpolated string | Use $ before the string | string name = "John"; string s = $"Hello, {name}!"; |
This table summarizes the basic syntax for different string operations in C#.
Booleans:
- ( YES / NO ), ( ON / OFF ), and ( TRUE / FALSE ).
bool isFinish = true;
bool isNotFinish = false;
Console.WriteLine(isFinish); //Outputs: True
Console.WriteLine(isNotFinish); //Output: False
Console.WriteLine(10>9); //Output: True
Console.WriteLine(10==10); //Output: True
Console.WriteLine(10==12); //Output: False
Console.WriteLine(10>=7); //Output: True
if...else if...else: Syntex:
if (condition)
{
//Block of Code
}else if(condition 2){
//Block of Code
}else {
//Block of Code
}
Example:
int time = 22;
if (time < 10)
{
//Not execute
}else if(time == 22){
//Execute
}else {
//Not execute
}
Ternary Operator:
Syntex:
variable = condition ? executeTruePartOfCode : executeFalsePartOfCode;
Example:
Console.WriteLine((2>1)?"2 is gratter":"1 is gratter");
Switch Case:
The
switch
statement works with various types of variables includingint
,char
,string
,bool
andenums
. It also supports pattern matching.Each
case
label must be a constant value.You cannot have duplicate
case
labels in the sameswitch
statement.Each
case
label ends with a colon (:
).Each
case
typically ends with abreak
statement another wize it go to the nextcase
.The
default
case is optional but recommended.It executes if none of the other cases match the switch expression.
Syntex:
switch(expression) { case x: // code block break; case y: // code block break; default: // code block break; }
Example:
int day = 4; switch (day) { case 1: Console.WriteLine("Monday"); break; case 2: Console.WriteLine("Tuesday"); break; case 3: Console.WriteLine("Wednesday"); break; case 4: Console.WriteLine("Thursday"); break; case 5: Console.WriteLine("Friday"); break; case 6: Console.WriteLine("Saturday"); break; case 7: Console.WriteLine("Sunday"); break; } // Outputs "Thursday" (day 4)
C# 7.0 introduced
pattern matching
, allowing more complex conditions inswitch
statements.Example:
string command = "start"; switch (command) { case "start": Console.WriteLine("Starting"); break; case "stop": Console.WriteLine("Stopping"); break; case "pause": Console.WriteLine("Pausing"); break; default: Console.WriteLine("Unknown command"); break; }
Example: Type Pattern Matching with switch
:
If
obj
is anint
, the value is assigned to the variablei
, and the corresponding block is executed, printing the integer value.If
obj
is astring
, the value is assigned to the variables
, and the corresponding block is executed, printing the string value.If
obj
isnull
, the corresponding block is executed, printing"Null"
.object obj1 = "Hello"; switch (obj1) { case int i: Console.WriteLine($"Integer: {i}"); break; case string s when s.Length > 5: Console.WriteLine($"Long string: {s}"); break; default: Console.WriteLine("Other type or shorter string"); break; }
Example: Pattern Matching with Additional Conditions:
If
obj1
is anint
, the value is assigned to the variablei
, and thecorresponding block is executed
, printing theinteger value
.If
obj1
is astring
and itslength is greater than 5
, the value is assigned to the variables
, and thecorresponding block is executed
, printing thestring value
.object obj1 = "Hello"; switch (obj1) { case int i: Console.WriteLine($"Integer: {i}"); break; case string s when s.Length > 5: Console.WriteLine($"Long string: {s}"); break; default: Console.WriteLine("Other type or shorter string"); break; }
Example: Switch Expression:
Introduced in C# 8.0, which provides a more concise syntax for assigning a value based on the matched case.
The
switch
expression evaluates the value ofvariable
and matches it against the specified patterns.The underscore
_
serves as a wildcard pattern that matches any value not covered by the previous cases. The expression evaluates to"Default result"
.The
result
variable will be assigned the value corresponding to the matched case. This approach simplifies the assignment logic compared to a traditionalswitch
statement.var result = variable switch { value1 => "Result for value1", value1 => "Result for value2", _ => "Default result", };
int variable = 1; var result = variable switch { 1 => "Result for value1", 2 => "Result for value2", _ => "Default result", }; Console.WriteLine(result);
While Loop:
Syntax:
while(condition) { //Code block };
Example:
int i = 1; while(i<5) { Console.WriteLine(i); i++; };
do While Loop:
Syntax:
do { //Code block } while(condition);
Example:
int i = 1; do { Console.WriteLine(i); i++; }while(i<5);
For Loop:
Syntax:
for (statement 1; statement 2; statement 3) { // code block to be executed }
Example:
for (int i = 0; i < 5; i++) { Console.WriteLine(i); }
Nested Loop:
Example:
// Outer loop for (int i = 1; i <= 2; ++i) { Console.WriteLine("Outer: " + i); // Executes 2 times // Inner loop for (int j = 1; j <= 3; j++) { Console.WriteLine(" Inner: " + j); // Executes 6 times (2 * 3) } }
Foreach loop:
There is also a foreach loop, which is used exclusively to loop through elements in an
array
:Syntax:
foreach (type variableName in arrayName) { // code block to be executed }
Example:
string[] cars = {"Volvo", "BMW", "Ford", "Mazda"}; foreach (string i in cars) { Console.WriteLine(i); }
Break & Continue:
The
break
statement used to jump out of a loop.The
continue
statement breaks oneiteration
(in the loop), if aspecified condition occurs
, andcontinues with the next iteration in the loop
.
GOTO Statments:
- The
goto
statement is used to jump to a specific part of the code.
How to Use:
Label: First, you create a label in your code. A label is a name followed by a colon (
:
).Jump: Then, you use
goto
to jump to that label.
Example:
using System;
class Program
{
static void Main()
{
Console.WriteLine("Start");
goto JumpHere; // Jump to the label
Console.WriteLine("This will be skipped");
JumpHere: // Label
Console.WriteLine("End");
}
}
Explanation:
"Start" is printed first.
goto JumpHere;
tells the program to jump to the labelJumpHere
.The line
Console.WriteLine("This will be skipped");
is skipped.The label
JumpHere:
marks where the program continues, so "End" is printed next.
Caution:
- Using
goto
can make your code hard to read and understand. It's better to use loops and other control structures when possible.
Array:
Array is collection of homogeneous data items. It allows you to store multiple values in a single variable, and you can access each item using an index. Basically we have three types of arrays.
Single dimension;
Multiple dimension;
Jagged array;
Syntex of Array:- <data type>[] <array name>=new <data type> [size];
.
Rank specifier is used to specify the dimension of array.
[ ] - one dimension array.
[,] - two dimension array.
[,,] - three dimension array /multi dimension array.
[ ][ ] - Jagged array (array of arrays).
Advantages of Arrays:
Searching and sorting: By using array we can easily perform searching and sorting.
Efficient Storage: Arrays let you store multiple values in one variable, making it easier to manage data. Array is a user defined data type which is used to store multiple values of single variable of same data type.
Easy Access: You can quickly access any item using its index.
Memory Management: Arrays can help in managing memory efficiently since they store data in contiguous memory locations.
Better Performance: Accessing elements by index is fast, which can improve performance in certain applications.
Simplified Code: Using arrays can make your code cleaner and easier to understand when dealing with multiple related values.
Index: Index of the array will always, with 0 and ends with (size -1).
To declare an array, define the variable type with square brackets: string[] cars;
..
We have now declared a variable that holds an array of strings.
To insert values to it, we can use an array literal - place the values in a comma-separated list, inside curly braces: string[] cars = {"Volvo", "BMW", "Ford", "Mazda"};
.
To create an array of integers, you could write: int[] myNum = {10, 20, 30, 40};
.
Access the Elements of an Array: You access an array element by referring to the index number like that string[] cars = {"Volvo", "BMW", "Ford", "Mazda"}; Console.WriteLine(cars[0]); // Outputs Volvo
.
Change an Array Element: To change the value of a specific element, refer to the index number like cars[0] = "Opel";
.
Array Length: To find out how many elements an array has, use the Length
property like that Console.WriteLine(cars.Length);
.
Example:-
using System;
namespace Array
{
internal class Program
{
static void Main(string[] args)
{
//Declear array:-
int[] num = new int[] {2,1,4,5,6,7};
Console.WriteLine("2: "+num[2]);
foreach (int i in num)
{
Console.WriteLine(i);
}
//Inslize the value in array:-
int[] num1 = new int[5];
Console.WriteLine("Enter 5 elements:-");
for (int i = 0; i< num1.Length; i++)
{
Console.WriteLine($"Enter the {i} elements: ");
num1[i] = Convert.ToInt32(Console.ReadLine());
}
//Printing the value of array:-
Console.WriteLine("All Enter element's: ");
for (int i = 0; i < num1.Length; i++)
{
Console.WriteLine(num1[i]);
}
Console.ReadKey();
}
}
}
Pass refren to coppy the array:
using System;
namespace Practical_Exercises
{
class Program2
{
static void Main()
{
Console.WriteLine("Array:- ");
int[] arr = new int[] { 1, 2, 3, 4, 5 };
int[] arr2 = new int[5];
Console.WriteLine("Befor doing any things");
foreach (int i in arr ) Console.Write(i+" ");//1 2 3 4 5
Console.WriteLine();
foreach (int i in arr2 ) Console.Write(i+" ");//0 0 0 0 0
Console.WriteLine("\nCopy or pass refrence");
arr2 = arr;//Pass refrence of arr to arr2 (refrence mins first element index address pass arr to arr2).
foreach (int i in arr) Console.Write(i + " ");//1 2 3 4 5
Console.WriteLine();
foreach (int i in arr2) Console.Write(i + " ");//1 2 3 4 5
Console.WriteLine("\nChange the value of arr then automaticly change arr2");
arr[2] = 58;
foreach (int i in arr) Console.Write(i + " ");//1 2 3 4 5
Console.WriteLine();
foreach (int i in arr2) Console.Write(i + " ");//1 2 3 4 5
Console.ReadLine();
}
}
}
In that example, one problem is that when we change any value in array of arr
, the value in arr2
automatically changes because we pass the reference of arr
to arr2
. This means we pass the address of the first element of arr
to arr2
, and arr2
gets the address of the first element and accesses all the array values. The reference is stored in stack memory, while all the array values are stored in heap memory.
Convert String to Character Array:
string str = "Mritunjay Kumar";
char[] c = str.ToCharArray();//{'M','r','i','t','u','n','j',}
Convert char array back to string:
string newStr = new string(c);
Syntex:
Single dimension:- A single-dimensional array is the simplest form of an array. It's like a list of items arranged in a sequence.
Syntex:
datatype[ ] anyname = new datatype [size];
.Example:
//Example 1: int[] numbers = new int[5]; // Create an array of five elements, and add values later numbers[0] = 10; numbers[1] = 20; numbers[2] = 30; numbers[3] = 40; numbers[4] = 50; //Example 2: // Create an array of four elements and add values right away string[] cars = new string[4] {"Volvo", "BMW", "Ford", "Mazda"}; //Example 3: // Create an array of four elements without specifying the size string[] cars = new string[] {"Volvo", "BMW", "Ford", "Mazda"}; //Example 4: // Create an array of four elements without using the new keyword and without specifying the size. string[] cars = {"Volvo", "BMW", "Ford", "Mazda"};
Multi dimension:- A multi-dimensional array can be thought of as a table or a grid, where data is stored in rows and columns.
Syntex:
datatype[,] anyname = new datatype[rows size, columns size];
.Example of 2 dimension array:
Declear and Printing value:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Method { internal class TwoDArray { static void Main(string[] args) { //Initialisation of two dim array int[,] numbers = new int[,] { { 10, 20, 30 }, { 40, 50, 60 } }; Console.WriteLine("Two Dim array elements are"); int i, j; for (i = 0; i < 2; i++) { for (j = 0; j < 3; j++) { Console.Write(numbers[i, j] + "\t"); } Console.WriteLine("\n"); } Console.ReadKey(); } } }
Initialisation Value:
//Example 1: // Create a 2D array with 3 rows and 3 columns, and add values later int[,] matrix = new int[3, 3]; matrix[0, 0] = 1; matrix[0, 1] = 2; matrix[0, 2] = 3; matrix[1, 0] = 4; matrix[1, 1] = 5; matrix[1, 2] = 6; matrix[2, 0] = 7; matrix[2, 1] = 8; matrix[2, 2] = 9; //Example 2: // Create and initialize a 2D array with values right away int[,] matrix = new int[3, 3] { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; //Example 3: // Create and initialize a 2D array without specifying the size int[,] matrix = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };
Accepting elements from user:-
using System; namespace Method { internal class TwoDArray { static void Main(string[] args) { //Accepting value from user of two dim array int[,] numbers = new int[2,2]; Console.WriteLine("Two Dim array elements are"); int i, j; for (i = 0; i < 2; i++) { for (j = 0; j < 2; j++) { numbers[i,j] = Convert.ToInt32(Console.ReadLine()); } } Console.ReadKey(); } } }
Three Dim Arrays or Multi Dim arrays:
Example:- Int [,,] numbers = new int [2,3,2];
2 - Semesters, 3 - Subjects, 2 - Papers
using system; namespace ThreeDimArray { class Program { static void Main(string[] args) { //three dim array demo1 // 2 semesters, 3 subjects and 2 papers int[,,] marks = new int[2, 3, 2]; int i, j, k; Console.WriteLine("enter marks in 12 subjects :"); for(i=0;i<;2;i++)//sems { Console.WriteLine("enter marks for Sem "+(i+1)); for(j=0;j<;3;j++)//subjects { if(j==0) Console.WriteLine(" Maths "); else if(j==1) Console.WriteLine(" Physics "); else Console.WriteLine(" Chemistry "); for(k=0;k<;2;k++)// papers { if(k==0) Console.Write(" Paper 1: "); else Console.Write(" Paper 2:"); marks[i, j, k] = Convert.ToInt32(Console.ReadLine()); }//end of papers }//end of subjs }//end of sems Console.ReadKey(); } } }
Jagged Array:- An array of arrays, where each sub-array can be of different size. The inner arrays can have different sizes. Where each element can have a different size. It's useful when the inner arrays don't need to be of the same size.
Jagged arrays are also called as Array of Arrays. We can also call them as Two dim arrays with varying columns.
Syntex:
datatype[][] arrayName = new datatype[size][];
Example:- .
static void Main(string[] args) { //working with Jagged Arrays int[][] marks = new int[4][]; marks[0] = new int[] {10,20,30,40 }; marks[1] = new int[] { 10, 20, 30, 40,50,60 }; marks[2] = new int[] { 10, 20, 30 }; marks[3] = new int[] { 10, 20, 30, 40,50,60,70,80 }; Console.WriteLine("Jagged Array elements are :"); for(int i=0;i<4;i++) { for(int j=0;j<marks[i].Length;j++) { Console.Write(marks[i][j]+","); } Console.WriteLine(); } Console.ReadKey(); }
Example:
//Example 1: // Create a jagged array with 3 elements, and initialize the inner arrays later int[][] jaggedArray = new int[3][]; jaggedArray[0] = new int[2]; // First inner array with 2 elements jaggedArray[1] = new int[3]; // Second inner array with 3 elements jaggedArray[2] = new int[1]; // Third inner array with 1 element jaggedArray[0][0] = 1; jaggedArray[0][1] = 2; jaggedArray[1][0] = 3; jaggedArray[1][1] = 4; jaggedArray[1][2] = 5; jaggedArray[2][0] = 6; //Example 3: // Create and initialize a jagged array right away int[][] jaggedArray = new int[][] { new int[] {1, 2}, // First inner array with 2 elements new int[] {3, 4, 5}, // Second inner array with 3 elements new int[] {6} // Third inner array with 1 element }; //Example 4: // Create and initialize a jagged array without specifying the size int[][] jaggedArray = { new int[] {1, 2}, // First inner array with 2 elements new int[] {3, 4, 5}, // Second inner array with 3 elements new int[] {6} // Third inner array with 1 element };
Define the Array size at runtime:
//1D Array:
int size = 10; // Size determined at runtime
int[] array1D = new int[size];
//2D Array:
int rows = 3; // Number of rows determined at runtime
int columns = 4; // Number of columns determined at runtime
int[,] array2D = new int[rows, columns];
//3D Array:
int dim1 = 2; // Size of the first dimension determined at runtime
int dim2 = 3; // Size of the second dimension determined at runtime
int dim3 = 4; // Size of the third dimension determined at runtime
int[,,] array3D = new int[dim1, dim2, dim3];
//Jagged Array:
int outerSize = 3; // Size of the outer array determined at runtime
int innerSize1 = 2; // Size of the first inner array determined at runtime
int innerSize2 = 4; // Size of the second inner array determined at runtime
int innerSize3 = 3; // Size of the third inner array determined at runtime
// Define the outer array
int[][] jaggedArray = new int[outerSize][];
// Initialize each inner array with different sizes
jaggedArray[0] = new int[innerSize1];
jaggedArray[1] = new int[innerSize2];
jaggedArray[2] = new int[innerSize3];
Single-Dimensional Array: A simple list of items arranged in a sequence.
Multi-Dimensional Array: A table or grid of items with rows and columns.
Jagged Array: An array of arrays where each inner array can be of different sizes.
Loop an Array:
- Using for loop:
string[] cars = {"Volvo", "BMW", "Ford", "Mazda"};
for (int i = 0; i < cars.Length; i++)
{
Console.WriteLine(cars[i]);
}
Using foreach loop:
- Syntex:
foreach (type variableName in arrayName)
{
// code block to be executed
}
- Example:
string[] cars = {"Volvo", "BMW", "Ford", "Mazda"};
foreach (string i in cars)
{
Console.WriteLine(i);
}
//foreach also work in string.
What is the difference between array and jagged array in C#?
- Ans: In a multidimensional array, each element in each dimension has the same, fixed size as the other elements in that dimension. In a jagged array, which is an array of arrays, each inner array can be of a different size.
Drawbacks of arrays.
We cannot store different types of elements in an array.
We cannot change the size of an array (we cannot increase or decrease it).
If we store fewer elements, it leads to wasted memory.
An array is also called static memory allocation.
Inserting an element into an existing array is difficult. We need to write logic to move the existing elements to the next cells.
Removing an element also requires logic to move the elements to the previous cells.
Memory Allocation:
Arrays are reference types in C#.
The reference to the array is stored on the stack if the array is a local variable.
The actual array data (the elements of the array) is stored on the heap.
Example:
public void ExampleMethod()
{
int[] numbers = new int[5]; // Array of integers
numbers[0] = 10;
numbers[1] = 20;
// and so on...
}
Reference to the Array:
numbers
is a reference to an array.Since
numbers
is a local variable, the reference to the array is stored on the stack.
Actual Array Data:
The actual array (the block of memory that can hold 5 integers) is allocated on the heap.
The values
10
,20
, and so on are stored within this block of memory on the heap.
Diagram for Clarity:
simplified diagram to illustrate the memory allocation:
Stack: +--------------------+ | numbers (reference)| ------> +-------------------+ | | | [0] = 10 | | | | [1] = 20 | | | | [2] = 0 | | | | [3] = 0 | | | | [4] = 0 | +--------------------+ +-------------------+
The
numbers
variable, which is a reference to the array, is stored on the stack. The actual array with its elements is stored on the heap.
The reference to the array is stored on the stack (if the array is a local variable).
The actual data (the elements of the array) is stored on the heap.
The difference between the two array declarations is the following:
Implicitly Typed Array Initialization:
string[] s = { "Mritunjay", "Kumer" };
In this case, the array
s
is declared and initialized using an array initializer.The type of the array (
string[]
) is explicitly declared.The compiler infers the size of the array based on the number of elements provided in the curly braces.
The compiler automatically translates this to an array creation with the
new
keyword behind the scenes and converts it tonew string[] { "Mritunjay", "Kumer" }
.
Explicitly Typed Array Initialization:
string[] s1 = new string[] { "Mritunjay", "Kumer" };
Here, the array
s1
is declared and initialized using thenew
keyword and an array initializer.The type of the array (
string[]
) is explicitly declared, and the array is explicitly created using thenew
keyword.This form is more explicit about the array creation.
Key Differences:
Syntax:
The first form is shorter and more concise.
The second form is more explicit about the array creation process.
Usage:
Both forms achieve the same result: creating and initializing an array with the specified values.
The choice between them is mostly a matter of style and preference. The first form is often used for simplicity and conciseness, while the second form may be preferred for its explicitness, especially in more complex scenarios where clarity is important.
Methods:
A method is a block of code which only runs when it is called.
You can pass data, known as parameters, into a method.
Methods are used to perform certain actions, and they are also known as functions.
Why use methods? To Code Reusability: define the code once, and use it many times. Organization: Break down complex problems into smaller, manageable pieces. Maintainability: Easier to update and fix code. Readability: Makes code easier to understand by giving descriptive names to actions.
When to use Methods? Use methods when you have a task or logic that you will need to perform multiple times or when you want to organize your code into logical sections.
Method is a group of statements having a name used for a specific purpose. It may or may not return a value.
Methods are of two types:
Pre-defined methods (Built-in) : These are given by C#
User defined methods: We need to define our own methods.
In a predefined method, the method definition includes the method name, parameters, and return type.
How Methods Work:
Definition: Define a method with a name, parameters (optional), and a return type (optional).
Calling: Call the method from other parts of the program to execute its code.
Method Syntax:
returnType MethodName(parameters)
{
// Method body
// Code to execute
return value; // if the return type is not void
}
Or:
<Access Modifier><Return Type><Method Name>(Parameter list)
{
//Body of Method
//Code to Be Executed
}
Example:-
static void Hello()
{
Console.WriteLine("Hello world");
}
Method name: Hello
Return type : void (not returning any value)
Parameters : no parameters
Note: If return type is void then we need not return any value from a method. Other than void if you write like int,string,double,bool etc. we have to write return statement.
Create a Method:
A method is defined with the method's name, followed by parentheses (). C# has some built-in methods, like Main()
, but you can also create your own methods to do specific tasks:
Create a method inside the Program class:
class Program
{
static void PrintHello()
{
// code to be executed
}
}
PrintHello() is the name of the method.
static
means that the method belongs to the Program class and not an object of the Program class. You will learn more about objects and how to access methods through objects lets discuss.
Call a Method:
To call (execute) a method, write the method's name followed by two parentheses () and a semicolon**;**
In the following example,
PrintHello()
is used to print a text (the action), when it is called.Inside
Main()
, call thePrintHello()
method:static void PrintHello() { Console.WriteLine("I just got executed!"); } static void Main(string[] args) { PrintHello(); } // Outputs "I just got executed!"
A method can be called multiple times:
static void PrintHello() { Console.WriteLine("I just got executed!"); } static void Main(string[] args) { PrintHello(); PrintHello(); PrintHello(); } // I just got executed! // I just got executed! // I just got executed!
Detailed Examples:
Example 1: A Simple Method
// A method that greets a user
void Greet(string name)
{
Console.WriteLine("Hello, " + name + "!");
}
// Calling the Greet method
Greet("Alice"); // Outputs: Hello, Alice!
Example 2: Method with Return Type
// A method that calculates the square of a number
int Square(int number)
{
return number * number;
}
// Calling the Square method
int squareOfFive = Square(5); // Outputs: 25
Console.WriteLine(squareOfFive); // Outputs: 25
Example 3: Method Overloading
// Method overloading: same method name with different parameters
void Display(int number)
{
Console.WriteLine("Number: " + number);
}
void Display(string text)
{
Console.WriteLine("Text: " + text);
}
// Calling overloaded methods
Display(10); // Outputs: Number: 10
Display("Hello"); // Outputs: Text: Hello
Advantages of Methods:
Modularity: Divide complex tasks into smaller methods.
Reusability: Use the same method in different parts of the program.
Readability: Easier to read and understand code.
Maintainability: Easier to fix and update code since you only need to change the method definition.
Disadvantages of Methods
Overhead: Calling methods can add a small overhead, especially if methods are called very frequently in performance-critical code.
Complexity: Too many small methods can make the codebase more complex and harder to follow.
Dependency: Methods that depend on other methods or global state can be hard to debug and maintain.
Parameters and Arguments:
Information can be passed to methods as parameters. Parameters work like variables inside the method.
They are listed after the method name, inside the parentheses. You can add as many parameters as you need, just separate them with a comma.
static void PrintHello(string fname) { Console.WriteLine(fname); } static void Main(string[] args) { PrintHello("Mritunjay"); PrintHello("Student"); } // Mritunjay // Student
This method that takes a string called fname as parameter. When the method is called, we pass along a first name, which is used inside the method to print the full name.
When a parameter is passed to the method, it is called an argument. So, from the example above:
fname
is a parameter, whileMritunjay
andStudent
are arguments.
Multiple Parameters :
You can have as many parameters as you like, just separate them with commas.
Example:-
static void MyMethod(string fname, int age) //fname and age are argument
{
Console.WriteLine(fname + " is " + age);
}
static void Main(string[] args)
{
MyMethod("Liam", 5); //Liam and 5 are parameters.
MyMethod("Jenny", 8);
MyMethod("Anja", 31);
}
// Liam is 5
// Jenny is 8
// Anja is 31
Note that when you use multiple parameters, the method call must have the same number of arguments as there are parameters, and the arguments must be in the same order.
Note: When you use multiple parameters to call method, the number of parameters and the number of arguments are same and must be in the same order's.
Use Default Parameter Value:
You can also use a default parameter value, by using the equals sign (=
).
If we call the method without an argument, it uses the default value ("Apple"):
using System;
class Program
{
static void PrintFruit(string fruit = "Apple")
{
Console.WriteLine(fruit);
}
static void Main(string[] args)
{
PrintFruit("Banana");
PrintFruit("Orange");
PrintFruit();
PrintFruit("Mango");
}
}
//Banana
//Orange
//Apple
//Mango
A parameter with a default value is known as an "optional parameter".
Named Arguments:
It is also possible to send arguments with the key: value
syntax. That way, the order of the arguments does not matter:
Example:
static void MyMethod(string child1, string child2, string child3)
{
Console.WriteLine("The youngest child is: " + child3);
}
static void Main(string[] args)
{
MyMethod(child3: "John", child1: "Liam", child2: "Liam");
}
// The youngest child is: John
Return Values:
Methods with return values are a fundamental concept in C# programming, allowing for modular, reusable, and clear code. They perform tasks and send back results to the calling code, enhancing the flexibility and functionality of programs. Proper handling of return values is essential for effective and error-free coding.
This means that after performing their task, they can send a value back to the place where they were called. This is useful for getting results from computations or operations performed within the method.
If you want the method to return a value, you can use a primitive data type (such as int
or double
) instead of void
, and use the return
keyword inside the method. Use the return
keyword followed by the value you want to return.
using System;
class Program
{
// Method to add two numbers and return the result
static int Add(int a, int b)
{
return a + b;
}
// Method to concatenate two strings and return the result
static string Concatenate(string str1, string str2)
{
return str1 + str2;
}
// Method to check if a number is even and return the result
static bool IsEven(int number)
{
return number % 2 == 0;
}
static void Main(string[] args)
{
// Calling the Add method and storing the result
int sum = Add(5, 3);
Console.WriteLine("Sum: " + sum); // Outputs: Sum: 8
// Calling the Concatenate method and storing the result
string combinedString = Concatenate("Hello, ", "World!");
Console.WriteLine("Combined String: " + combinedString); // Outputs: Combined String: Hello, World!
// Calling the IsEven method and storing the result
bool isEightEven = IsEven(8);
Console.WriteLine("Is 8 Even? " + isEightEven); // Outputs: Is 8 Even? True
}
}
/*
Sum: 8
Combined String: Hello, World!
Is 8 Even? True
*/
Advantages of Methods with Return Values
Modularity: Encapsulate logic and computations in reusable methods.
Reusability: Methods can be called multiple times and used in different contexts.
Clarity: Clear separation of tasks and results.
Flexibility: Methods can return various data types based on the need.
Method can be called in following way's
Call by Value
Call by Refrence
Call by Output
Call by Params
Call by Value:
using System;
namespace Practice
{
internal class Program
{
//Create method:-
static void CallByValueMethod(int x)
{
x = 100;
Console.WriteLine("InSide methof value of x is:-"+x); //100
}
static void Main(string[] args)
{
int a = 10;
Console.WriteLine("value a before calling method: "+a);//10
CallByValueMethod(a);//Call method with pass argument
//Not affact the `a` value in hear.
Console.WriteLine("value a after calling method: "+a);//10
}
}
}
- In Call by Value, any changes to the value of x inside the
CallByValueMethod
do not affect the value ofa
in the Main method.
Call by Refrence:
using System;
namespace Practice
{
internal class Program
{
//Create method:-
static void CallByValueRefrence(ref int x)
{
x = 100;
Console.WriteLine("InSide methof value of x is:-"+x); //100
}
static void Main(string[] args)
{
int a = 10;
Console.WriteLine("value a before calling method: "+a);//10
CallByValueRefrence(ref a);
//Affact the `a` value in hear.
Console.WriteLine("value a after calling method: "+a);//100
}
}
}
- When we use the
ref
keyword in an argument and parameter, it affects the original value. This is becauseref
passes a reference to the value, so any changes tox
inCallByValueReference
will affect the original value.
Call by Output:
- By using
out
, you can effectively return multiple values from a method, leveraging both the method's return value and theout
parameters.
using System;
namespace Practice
{
internal class Program
{
// Create method:-
static void CallByOutMethod(out int x)
{
x = 100; // Here, x is assigned the value 100
Console.WriteLine("Inside method, value of x is: " + x); // 100
}
static int CallByOutMethod2(out int x)
{
x = 84; // Here, x is assigned the value 84
Console.WriteLine("Inside method, value of x is: " + x); // 84
return 28;
}
static void Main(string[] args)
{
int a = 10;
Console.WriteLine("Value of a before calling method: " + a); // 10
CallByOutMethod(out a); // Waiting for the method to assign a value to a
Console.WriteLine("Value of a after calling method: " + a); // 100
int n = CallByOutMethod2(out a);
Console.WriteLine("Value of n is: " + n + " and a is: " + a); // n=28, a=84
}
}
}
- The
out
keyword is used to pass a reference to a variable and wait for the method to assign a value to it. If you want to useout
, you must use theout
keyword in both the argument and the parameter. Additionally, theout
parameter must be assigned a value before the method returns.
Call by Params:
- The
params
keyword lets a method take a variable number of arguments. You can pass a list of arguments to the method, and they will be treated as an array inside the method. This is helpful when you don't know in advance how many arguments you will pass.
Key Points:
Use of
params
: Theparams
keyword is used in the method parameter to indicate that the method can accept a variable number of arguments.Argument List: The arguments are passed as an array to the method.
Only One
params
: A method can have only oneparams
parameter, and it must be the last parameter in the method signature.
using System;
namespace Practice
{
internal class Program
{
// Create method using `params` keyword
static void PrintNumbers(params int[] numbers)
{
Console.WriteLine("Inside method, printing numbers:");
foreach (int number in numbers)
{
Console.WriteLine(number);
}
}
static void Main(string[] args)
{
// Calling the method with a variable number of arguments
PrintNumbers(1, 2, 3, 4); // Output: 1, 2, 3, 4
PrintNumbers(10, 20); // Output: 10, 20
PrintNumbers(); // No output as no arguments were passed
}
}
}
In params parameter, when you pass the argument and you want to send diffrent type of
// 01: Example: Correct way to use
static void PrintNumbers(string s2, params int[] numbers)
{}
static void Main(string[] args)
{
PrintNumbers("string",1, 2, 3, 4);
}
// 02: Example: Correct way to use
static void PrintNumbers(int i, params int[] numbers)
{}
static void Main(string[] args)
{
PrintNumbers(100, 1, 2, 3, 4);
}
// 02: Example: Wrong way to use
static void PrintNumbers(params int[] numbers, string s2,)
{}
static void Main(string[] args)
{
PrintNumbers(1, 2, 3, 4,"string");
}
// 03: Example: Wrong way to use
static void PrintNumbers(params int[] numbers, int i,)
{}
static void Main(string[] args)
{
PrintNumbers(1, 2, 3, 4, 100);
}
- When we use the
params
keyword in a method parameter, it allows the method to accept a variable number of arguments. This means you can pass multiple arguments to the method, and they will be treated as an array inside the method. If you want to useparams
, it must be the last parameter in the method signature, and you can only have oneparams
parameter per method.
Diffrence bitween out and ref parameter:
Example: ref
static void Main()
{
int number = 10; // Must be initialized
Console.WriteLine("Before calling ModifyRef: " + number); // Outputs 10
ModifyRef(ref number);
Console.WriteLine("After calling ModifyRef: " + number); // Outputs 20
}
static void ModifyRef(ref int x)
{
x = x + 10; // Modifies the original value
}
Explanation:
The variable
number
is initialized to10
before being passed to theModifyRef
method.The
ModifyRef
method takes aref
parameter, meaning it can read and modify the original value.Inside the method,
x
(which referencesnumber
) is increased by10
, changing its value to20
.After the method call, the original variable
number
reflects this change.
Example: out
static void Main()
{
int number; // No need to initialize
Console.WriteLine("Before calling AssignOut: uninitialized");
AssignOut(out number);
Console.WriteLine("After calling AssignOut: " + number); // Outputs 30
}
static void AssignOut(out int x)
{
x = 30; // Must assign a value before returning
}
Explanation:
The variable
number
is declared but not initialized.The
AssignOut
method takes anout
parameter, meaning it must assign a value tox
before returning.Inside the method,
x
is assigned the value30
.After the method call, the original variable
number
is now30
.Initialization Before Call:
ref
: The variable must be initialized before being passed to the method.out
: The variable does not need to be initialized before being passed to the method.
Reading Initial Value:
ref
: The method can read the initial value of the parameter.out
: The method cannot read the initial value because it assumes the variable is uninitialized.
Assigning Value:
ref
: The method can modify the existing value, but it doesn't have to assign a new value.out
: The method must assign a value to the parameter before returning.
Method working behind the screen:
When the method call it store in call stack.
I have one example understande it 1st:-
using System; namespace Recursion { internal class Program { static void Main(string[] args) { Console.WriteLine("1st: Main method run"); Method3(3); } static void Method3(int x) { Console.WriteLine($"3nd: Method run and x = {x}"); Method2(2); } static void Method2(int x) { Console.WriteLine($"2nd: Method run and x = {x}"); Method1(1); } //Method1 not call any methods static void Method1(int x) { Console.WriteLine($"1nd: Method run and x = {x}"); } } } //Output is:- //1st: Main method run //3nd: Method run and x = 3 //2nd: Method run and x = 2 //1nd: Method run and x = 1
Recursion
In previous last example,multiple method use same code then happen if the requiremr is 100 times, then we use recursion it mins function call itself.
using System;
namespace Recursion
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Main method run");
Method(3);
}
static void Method(int x)
{
Console.WriteLine($"x = {x}");
Method(x-1);
}
}
}
//Output is:-
//1st: Main method run
//x = 3
//...
//...
//...
//Infnite time
In this example, the method calls itself infinitely, and each call is stored in the call stack. To stop the recursion, use a base condition
to end the new calls. like that:
using System;
namespace Recursion
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Main method run");
Method(3);
}
static void Method(int x)
{
if (x == 0)
{
return;
}
Console.WriteLine($"x = {x}");
Method(x-1);
}
}
}
//Output is:-
//1st: Main method run
//x = 3
//x = 2
//x = 1
If you are calling a function again and again, you can treat it as a sepret call in the stack. Also take seprate seprete memory. If you call the method infinitely, the stack/memory will fill up and it will give a stack overflow error
.
Base condition:- If you don't use a base condition, the method will keep calling itself, and the stack will keep filling up. Since each method call uses memory, after some time the computer memory will exceed the limit..
example:
if (x == 0)return;
Why we need recursion:
It help us in solving bigger/complex problom in a simple way.
You can convert recursion solution into iteration & vice versa.
Space complecity is not constant because of recursive calls.
It help us to braking down bigger problom to smaller problom.
Recursion Tree:-
Let's understand by question:-
Q.1: Find the N th fibonacci number?
0, 1, 1, 2, 3, 5, 8, 13, ........
Poin 1: How you identify that question solved by recursion or not.
Point 2: Break down the question in to smoll question or pice like that:
fabonacci(n) = fabonacci(n-1) + fabonacci(n-2)
//code:
using System;
namespace Practical_Exercises
{
internal class Program
{
static void Main()
{
Console.Write("Enter the number: ");
int n = Convert.ToInt32(Console.ReadLine());
Console.WriteLine($"Fibonacci of {n} position is {Fabo(n)}");
Console.ReadKey();
}
static int Fabo(int n)
{
if (n < 2) return n;
return Fabo(n-1) + Fabo(n-2);
}
}
}
//Output:-
//Enter the number: 4
//Fibonacci of 4 position is 3
How does that work internally? Let's understand it:
- One more thing:
Fabo(n-1)
andFabo(n-2)
are not the last lines in theFabo()
method. Also,Fabo(n-1) + Fabo(n-2)
is not the last line. The last line in theFabo()
method isreturn Fabo(n-1) + Fabo(n-2);
. In theMain()
method, the last line isConsole.ReadKey();
. The idea of the last line being a function call is related to tail recursion, where the final action of a function is to call itself.
How to understande and approach an problome:
Identify if you can break down the problem into smaller problems.
Write the recurrence relation if needed.
Draw the recurrence tree.
About the tree:
See the flow of methods and how they are getting into the stack.
Identify and focus on the left tree call and the right tree call.
First, do the left method, then do the right method.
Draw the tree and positions again and again using pen and paper.
Use a debugger to see the flow.
See how the values are returned at each step, and see where the method call will come out. In the end, you will come out of the main method.
Very important things to focus on when solving recursion:
Parameter.
Return Type.
Body of Code.
fabonacci(n) = fabonacci(n-1) + fabonacci(n-2) this is a recurence relation
Type of recurence relation:
Linear Recurrence Relations with Constant Coefficients (ex: Fibonacci Sequence).
Recurrence Relation: F(n)=F(n−1)+F(n−2).
With initial conditions F(0)=0 and F(1)=1.
Explanation: Each term in the Fibonacci sequence is the sum of the two previous terms.
Divide and Conquer Recurrence Relations (ex: Binary Search).
Recurrence Relation: T(n)=T(n/2)+O(1).
Explanation: Binary search splits the array in half each time, performing a constant amount of work in each step.
Non-Homogeneous Recurrence Relations (ex**:** Factorial Calculation).
Recurrence Relation: T(n)=T(n−1)+O(n).
with T(0) = 1.Explanation: Calculating the factorial of a number (n) can be defined recursively by multiplying the result of ((n-1)!) by (n), plus the extra step for the multiplication operation.
In that example, when you enter 50 to find the 50th Fibonacci number, the program gets stuck.
static void Main()
{
int n = 50
CW(Fabo(n));
}
static int Fabo(int n)
{
if (n < 2) return n;
return Fabo(n-1) + Fabo(n-2);
}
Can you see that :-
This code repeats itself. Imagine how many times it will repeat if you input 50. That why program getting stuck.
Passing an array to a method & Return an array from a method:
Passing an Array to a Method:
When you pass an array to a method, you provide the method with the array reference. The method can then access and modify the elements of the array.
syntex:-ReturnType MethodName(DataType[] arrayParameter) { // Method body }
Example:-
using System;
class Program
{
// Method that takes an array as a parameter and prints its elements
static void PrintArray(int[] array)
{
foreach (int item in array)
{
Console.WriteLine(item);
}
}
static void Main()
{
int[] numbers = { 1, 2, 3, 4, 5 };
PrintArray(numbers);
}
}
Returning an Array from a Method:
You can also return an array from a method. The return type of the method should be the array type.
Syntex:-DataType[] MethodName() { // Method body that creates and returns an array }
.
Example:-
using System;
class Program
{
// Method that returns an array of integers
static int[] GenerateArray(int size)
{
int[] array = new int[size];
for (int i = 0; i < size; i++)
{
array[i] = i * 2; // Just an example of initialization
}
return array;
}
static void Main()
{
int[] generatedArray = GenerateArray(5);
// Print the returned array
foreach (int item in generatedArray)
{
Console.WriteLine(item);
}
}
}
Combining Both: Passing an Array and Returning an Array:
using System;
class Program
{
// Method that takes an array, modifies it, and returns a new array
static int[] ModifyArray(int[] array)
{
return array;
}
static void Main()
{
int[] originalArray = { 1, 2, 3, 4, 5 };
int[] newArray = ModifyArray(originalArray);
}
}
Params:
It is used to pass variable no. of arguments to a method.
In C#, params
is a keyword used in method parameters to specify that the method can accept a variable number of arguments of a particular type. It allows you to pass a variable number of parameters to a method as an array.
Stntex:ReturnType MethodName(params DataType[] parameterName) { // Method body }
.
params: It indicates that the parameter array can accept zero or more arguments of the specified type.
DataType[] parameterName: This is the parameter array declaration. It can accept multiple arguments of type DataType
.
using System;
class Program
{
// Method that calculates the sum of integers using params
static int Sum(params int[] numbers)
{
int sum = 0;
foreach (int num in numbers)
{
sum += num;
}
return sum;
}
static void Main()
{
// Calling the Sum method with different number of arguments
int result1 = Sum(1, 2, 3); // Passing 3 arguments
int result2 = Sum(4, 5); // Passing 2 arguments
int result3 = Sum(6, 7, 8, 9, 10); // Passing 5 arguments
Console.WriteLine("Result 1: " + result1); // Output: 6
Console.WriteLine("Result 2: " + result2); // Output: 9
Console.WriteLine("Result 3: " + result3); // Output: 40
}
}
Key Points
You can use
params
only for the last parameter in a method's parameter list.The
params
keyword must be followed by an array type.When calling a method with
params
, you can pass arguments directly without explicitly creating an array.
Benefits of Using params
Flexibility: It allows methods to accept a variable number of arguments, making them more flexible.
Convenience: You can pass arguments directly without creating an array explicitly.
Simplifies Method Overloading: Reduces the need for multiple method overloads for different parameter counts.
Limitations
The
params
parameter must be the last parameter in the method's parameter list.You can have only one
params
parameter in a method signature.
When to Use params
- Use
params
when you have methods that need to accept a variable number of arguments of the same type, such as in utility methods or mathematical operations where the number of operands can vary.
params
in C# provides a convenient way to work with methods that accept a variable number of arguments, simplifying the code and enhancing flexibility.
Exceptions and Exception Handling
Generally, when we develop the application, we get two different types of errors:
Compile-time error (Syntactical error called compile-time error).
Run-time error (The errors that occur during execution are called run-time errors).
Compile-time error:
Syntactical errors, also known as compile-time errors, are not dangerous and can be fixed during development. These errors occur when you run the program at the developing stage.
Run-time error:
Run-time errors happen when the program is running. They can be caused by wrong inputs, incorrect logic, database network problom missing necessary resources & etc. Example: Assume you have an array with a size of 5 and using a for loop you try to add a 6th value. At that time come error occur.These are dangerous because if a run-time error occurs, the program gets abnormally terminated without executing the next line of code. For example, assume you have 1000 lines of code. If an error occurs on the 100th line, the program will abnormally terminate, and the remaining 900 lines will not execute. Compile cannot check the logic, it only checks syntax because everyone implements different logic.
Who is responsible for abnormally terminated:
The exception is responsible for the program's abnormal termination. An exception is a class.
Whenever any error occurs in the program, the exception class is triggered, and it abnormally terminates the program.
An exception is not a run-time error itself. When run-time errors happen in the code, an exception occurs and causes of exception the program abnormally terminates. An exception is a class, and there are different classes for each type of run-time error. Example: IndexOutOfBoundsException
is a run-time error and the name of a class. This error occurs when you try to add more values than the size of the array. Because of the IndexOutOfBoundsException
class, your program abnormally terminates. For program abnormally terminates lot's of predefine class are available like DivideByZeroException, OverflowException, FormatException and etc. And all this class present in Exception
class.
How predefined exception classes are implemented in our library:
A class named Exception
is available with logic for abnormal termination. This class contains a readonly property to display an error message, which is declared as virtual (meaning child classes can overwrite it) and the property name is "Message.
Under this Exception, two child classes are defined:
Application Exception: This is a base class for exceptions that are specifically defined by your application. You can create custom exception classes derived from
ApplicationException
to handle specific errors unique to your program.System Exception: This is a base class for exceptions that are thrown by the .NET runtime system. It includes common errors like memory access violations or arithmetic overflows. Examples include
NullReferenceException
andIndexOutOfRangeException
.
In short, ApplicationException
is for custom errors in your code, while SystemException
is for general errors handled by the .NET system.
All the predefined exception come under the SystemException Like :
IndexOutOfBoundsException
Formet Exception
DivideByZeroException
OverflowException
Why this many error are available?
To clarify which type of error occurs in the program. Different types of errors occur in different scenarios. This all predefine class's.
using System;
class ExceptionHandle
{
static void Main()
{
Console.WriteLine(10/0);
}
}
Come error:- ExceptionHandle.cs(7,21): error CS0020: Division by constant zero
How the exception will arise: All the .NET applications running are monitored by the CLR. The CLR is going to monitor the application, and it is the execution engine responsible for running the program. All programs run under the supervision of the CLR. When execution is ongoing, the CLR identifies the mistake in the line, then the CLR stops the program and checks the mistake. After that, the CLR will pick the class associated with this mistake (like Division by constant zero). Now the CLR creates an instance of that class and throws the object. The object thrown by the CLR causes the program is terminate abnormally. Once the program terminates abnormally, it shows the message and does not execute the next line after the error line.
To handle the program terminate abnormally we use Exception handling.
Exception handling:
Exception handling is used to stop the abnormal termination of a program whenever a runtime error occurs in the program.
We can show user-friendly error messages to the end users to explain the error.
We can take corrective actions to fix problems that may happen because of the error like when money is transferred from one account to another, if there are two processes: first, deducting the money from one account, and second, adding the money to another account. But assume the first task completes, and when adding money to the other account an error occurs. This is where exception handling comes in. If any error occurs in the second task, then the first task is canceled.
To handle an exception, we use two special blocks: the first is try, and the second is catch.
using System;
class ExceptionHandle
{
static void Main()
{
try
{
//Statement's which will cause runtime error
//Statement's which doesn't require exception when the runtime error occured
}
catch(<Exception Class Name> <Variable>)
{
//Statement's which should execute only when there is a runtime error
}
}
}
Example:
using System;
class ExceptionHandle
{
static void Main()
{
Console.WriteLine("Hello World");
try
{
Console.WriteLine("We are try to run the exception code!");
Console.Write("Enter the \'a\' value: ");
int a = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter the \'b' value: ");
int b= Convert.ToInt32(Console.ReadLine());
int x = a/b;
Console.WriteLine("Your Answer is :" + x);
}
catch(DivideByZeroException ex)
{
Console.WriteLine(ex.Message);
}
}
}
/*Output is:-
Hello World
We are try to run the exception code!
Enter the 'a' value: 12
Enter the 'b' value: 0
Attempted to divide by zero.
*/
Here, the CLR creates an instance of the DivideByZeroException
class and throws it. This instance
is thrown by the CLR to perform the abnormal termination. However, because we use try-catch block, here, before performing the abnormal termination, the catch block catches the instance. Once the instance is caught by the catch block, the abnormal termination stops. Then the instance is stored in ex
. What is ex
? ex
is the variable of the class.
Remember, the instance of the class is assigned to the ex
variable of the class. Once the assignment is done, the variable (ex
) is a reference to the DivideByZeroException
class. Then the catch block performs the task.
Sometimes, this error also occurs in this code. The name of the error is FormatException
:
Hello World
We are try to run the exception code!
Enter the 'a' value
43
Enter the 'b' value
Mo
Unhandled Exception: System.FormatException: Input string was not in a correct format.
at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
at ExceptionHandle.Main()
To solve that, we use another catch block:
using System;
class ExceptionHandle
{
static void Main()
{
Console.WriteLine("Hello World");
try
{
Console.WriteLine("We are try to run the exception code!");
Console.Write("Enter the \'a\' value: ");
int a = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter the \'b' value: ");
int b= Convert.ToInt32(Console.ReadLine());
int x = a/b;
Console.WriteLine("Your Answer is :" + x);
}
catch(DivideByZeroException ex)
{
Console.WriteLine(ex.Message);
}
catch(FormatException ex1)
{
Console.WriteLine(ex1.Message);
}
}
}
/*Output is:
Hello World
We are try to run the exception code!
Enter the 'a' value: 3
Enter the 'b' value: f
Input string was not in a correct format.
*/
Assume you know only two errors can happen, and you handle them. But what if an unknown error occurs when the application is developed? To fix this, we use a parent class called Exception
in last catch block like that.
using System;
class ExceptionHandle
{
static void Main()
{
Console.WriteLine("Hello World");
try
{
Console.WriteLine("We are try to run the exception code!");
Console.Write("Enter the \'a\' value: ");
int a = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter the \'b' value: ");
int b= Convert.ToInt32(Console.ReadLine());
int x = a/b;
Console.WriteLine("Your Answer is :" + x);
}
catch(DivideByZeroException ex)
{
Console.WriteLine(ex.Message);
}
catch(FormatException ex1)
{
//Custome Error show:
Console.WriteLine("We cannot take another datatype value");
}
catch(Exception ex2)
{
Console.WriteLine(ex2.Message);
}
}
}
/*Output:-
Hello World
We are try to run the exception code!
Enter the 'a' value: 3
Enter the 'b' value: 4444444444444444444444444444444
3rd catch run: Value was either too large or too small for an Int32.
*/
Apart from these two exceptions, DivideByZeroException and FormatException, any other exception will go to the Exception
class. Specialty of this Exception
class is it catches any exception that is not handled by any of the other catch blocks like else block in if-else or default block in switch-case.
If the Exception
class is available, then why do we useDivideByZeroException
andFormatException
classes:
Because of 2 reasons: The 1st is to perform different approaches in different scenarios. It means knowing what action to take after encountering an error. I take one action if a DivideByZeroException
error occurs and another action if a FormatException
error occurs. The 2nd is if you use only the Exception
class and not any particular class, it takes a lot of time for the compiler to find the specific class and takes more time.
That way, we use the Exception
class last. If any error happens that does not match with the previously defined exceptions or catches, then only the last catch, which is the Exception
class, will handle it.
One more thing, if an exception does not occur, then none of the catch blocks will execute. If any exception occurs in the try block, it jumps to the catch block and searches for the catch block that handles this exception. If there is a match, abnormal termination does not happen, and it runs all statements that are present after the catch block. If the exception does not match any catch block, abnormal termination occurs.
using System;
class ExceptionHandle
{
static void Main()
{
try
{
Console.Write("Enter the \'a\' value: ");
int a = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter the \'b' value: ");
int b= Convert.ToInt32(Console.ReadLine());
int x = a/b;
Console.WriteLine("Your Answer is :" + x);
Console.WriteLine("I am run after the error come and i am also inside the try block");
}
catch(DivideByZeroException ex)
{
Console.WriteLine(ex.Message);
}
Console.WriteLine("I am run after the error come and i am also outside the try block");
}
}
/*Output:-
Enter the 'a' value: 2
Enter the 'b' value: 0
Attempted to divide by zero.
I am run after the error come and i am also outside the try block
*/
One more block is there named finally, Syntex:
try
{
//Statement's which will cause runtime error
//Statement's which doesn't require exception when the runtime error occured
}
catch(<Exception Class Name> <Variable>)
{
//Statement's which should execute only when there is a runtime error
}
finally
{
//Statement's run alwase if Exception come or not
}
This finally block always runs whether an exception occurs or not. Why do we need it? Assume you open a file to do some task, but an exception occurs, or you complete the work correctly. The finally block is used to close the file whether an exception happens or you complete the task both the case.
try
{
//Open a file
//Write into the file
/*If you close the file hear but if any error come in
writing into the file then close the file code not work.
That why we write the close file code in finaly block*/
}
catch(<Exception Class Name> <Variable>)
{
//if error come then run
}
finally
{
//close the file
}
If you close the file in the try block, but an error occurs while writing into the file, the code to close the file will not work. That is why we write the code to close the file in the finally block.
Finally block is mandatory for execution.
One thing you might be confused about is the purpose of using the finally block. We can also close the file after the catch block without using the finally block. Here is an example to clear the doubt:
using System;
class ExceptionHandle
{
static void Main()
{
try
{
Console.Write("Enter the \'a\' value: ");
int a = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter the \'b' value: ");
int b= Convert.ToInt32(Console.ReadLine());
if(b == 1)
{
return;
}
int x = a/b;
Console.WriteLine("Your Answer is :" + x);
}
catch(DivideByZeroException ex)
{
Console.WriteLine(ex.Message);
}
catch(Exception ex2)
{
Console.WriteLine("3rd catch run: "+ex2.Message);
}
finally
{
Console.WriteLine("Finaly block execute");
}
}
}
/*Output:-
Enter the 'a' value: 2
Enter the 'b' value: 1
Finaly block execute
*/
Hear what happens when we use return; in the if block. According to the return keyword, return is used to exit the method. It means when we use return inside the method, the method execution finishes and control goes outside the method. But here, in the try-catch-finally block, when we use return;, it doesn't go anywhere because the finally block runs in any how condition. It's mandatory.
some points:
Exception is caught by the catch block because the exception caught by the catch block does not cause abnormal termination.
Finally block runs in any condition, it's mandatory.
Without writing a catch block, if we use only the try-finally block, then the exception is not caught, causing abnormal termination happend, but the finally block will alwase execute.
using System; class ExceptionHandle { static void Main() { try { Console.Write("Enter the \'a\' value: "); int a = Convert.ToInt32(Console.ReadLine()); Console.Write("Enter the \'b' value: "); int b= Convert.ToInt32(Console.ReadLine()); int x = a/b; Console.WriteLine("Your Answer is :" + x); } finally { Console.WriteLine("Finaly block execute"); } } } /* Output:- Enter the 'a' value: 2 Enter the 'b' value: 0 Unhandled Exception: System.DivideByZeroException: Attempted to divide by zero. at ExceptionHandle.Main() Finaly block execute */
Application Exception:
In System Exception, when any error occurs, such as division by zero or any incorrect condition like dividing any number by zero, the CLR tracks this and throws an instance, causing abnormal termination.
In an Application Exception, the CLR does not throw the instance for abnormal termination. The programmer or application developer creates the class and throws the instance.
To create the instance of a class to throw the instance of a class:
ApplicationException ex = new ApplicationException("<Error message>");
throw ex; // throw the ex
Or
throw new ApplicationException("<Error message>");
Exactly CLR doing like same thing's.
Explain: ApplicationException ex = new ApplicationException("<Error message>");
On the left side of the = sign,
ApplicationException
is the class name andex
is the instance of the class or instance name.On the right side of the = sign,
ApplicationException
is a constructor of theApplicationException
class, andnew
is used to allocate memory.("<Error message>")
is a parameter to pass the error message.
Don't think too much about class and constructor; we will learn about them later.
Explain: throw new ApplicationException("<Error message>");
- Instance is created and thrown without needing to create the instance name. We require an instance name when calling any member, but if not calling any member, there is no need to create an instance name. So,
throw new ApplicationException("<Error message>");
this is an instance but unnamed.
Example: I make an exception when the divider value is an odd number, then the exception occurs.
try
{
Console.Write("Enter the \'a\' value: ");
int a = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter the \'b' value: ");
int b= Convert.ToInt32(Console.ReadLine());
if(b%2 > 0)
{
throw new ApplicationException("b vale is odd number!");
}
int x = a/b;
Console.WriteLine("Your Answer is :" + x);
}
catch(Exception ex2)
{
Console.WriteLine(ex2.Message);
}
finally
{
Console.WriteLine("Finaly block execute");
}
/*Output:-
Enter the 'a' value: 2
Enter the 'b' value: 3
b vale is odd number!
Finaly block execute
*/
try
{
Console.Write("Enter the \'a\' value: ");
int a = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter the \'b' value: ");
int b= Convert.ToInt32(Console.ReadLine());
if(b%2 > 0)
{
throw new ApplicationException("b vale is odd number!");
}
int x = a/b;
Console.WriteLine("Your Answer is :" + x);
}
catch(ApplicationException ex2)
{
Console.WriteLine(ex2.Message);
}
finally
{
Console.WriteLine("Finaly block execute");
}
/*Output:-
Enter the 'a' value: 2
Enter the 'b' value: 3
Unhandled Exception: System.ApplicationException: b vale is odd number!
at ExceptionHandle.Main()
Finaly block execute
*/
try
{
Console.Write("Enter the \'a\' value: ");
int a = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter the \'b' value: ");
int b= Convert.ToInt32(Console.ReadLine());
if(b%2 > 0)
{
throw new ApplicationException("b vale is odd number!");
}
int x = a/b;
Console.WriteLine("Your Answer is :" + x);
}
catch(ApplicationException ex2)
{
Console.WriteLine(ex2.Message);
}
finally
{
Console.WriteLine("Finaly block execute");
}
/*Output:-
Enter the 'a' value: 2
Enter the 'b' value: 3
b vale is odd number!
Finaly block execute
*/
Remember Points:
If you do not pass the message like
throw new ApplicationException();
, then the error will beError in the application.
If you do not handle the programmer-defined exception, an error will occur.
ApplicationException is a class provided by the .NET Framework that serves as a base class for application-defined exceptions. It allows you to create custom exceptions that can be used to handle specific error conditions in your application.
In that error Unhandled Exception: System.ApplicationException: b vale is odd number! at ExceptionHandle.Main()
, I want to replace System.ApplicationException
with System.DivideByOddNumberException
. How do I do that?
To do that, we need our own class. To define our own Exception class:
Example:
using System;
public class DivideByOddNumberException: ApplicationException
{
public override string Message
{
get
{
return "Attempted to divide by odd number.";
}
}
}//End DivideByOddNumberException class
class ExceptionHandle
{
static void Main()
{
try
{
Console.Write("Enter the \'a\' value: ");
int a = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter the \'b' value: ");
int b= Convert.ToInt32(Console.ReadLine());
if(b%2 > 0)
{
throw new DivideByOddNumberException();
}
int x = a/b;
Console.WriteLine("Your Answer is :" + x);
}
catch(DivideByOddNumberException ed)
{
Console.WriteLine(ed.Message);
}
finally
{
Console.WriteLine("Finaly block execute");
}
}
}
/*Output:-
Enter the 'a' value: 5
Enter the 'b' value: 3
Attempted to divide by odd number.
Finaly block execute
*/
A file can contain multiple classes, but remember only one class can have the Main()
method.
Here, DivideByOddNumberException inherits from ApplicationException, and ApplicationException inherits from the Exception class. In the Exception class, there is a virtual read-only property named Message. You can override this property. By default, the message in the Message property is Error in the application
, but I need my own message.
Not work when you do not throw the programmer-created exception like here DivideByOddNumberException
is a programmer-created exception.
using System;
public class DivideByOddNumberException: ApplicationException
{
public override string Message
{
get
{
return "Attempted to divide by odd number.";
}
}
}
class ExceptionHandle
{
static void Main()
{
try
{
Console.Write("Enter the \'a\' value: ");
int a = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter the \'b' value: ");
int b= Convert.ToInt32(Console.ReadLine());
int x = a/b;
Console.WriteLine("Your Answer is :" + x);
}
catch(DivideByOddNumberException ed)
{
Console.WriteLine(ed.Message);
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
Console.WriteLine("Finaly block execute");
}
}
}
/*Output is:-
Enter the 'a' value: 9
Enter the 'b' value: 3
Your Answer is :3
Finaly block execute
*/
You see, here DivideByOddNumberException does not work because we did not throw it in the try block.
using System;
public class DivideByOddNumberException: ApplicationException
{
public override string Message
{
get
{
return "Attempted to divide by odd number.";
}
}
}//End DivideByOddNumberException class
class ExceptionHandle
{
static void Main()
{
try
{
Console.Write("Enter the \'a\' value: ");
int a = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter the \'b' value: ");
int b= Convert.ToInt32(Console.ReadLine());
if(b%2 > 0)
{
throw new DivideByOddNumberException();
}
int x = a/b;
Console.WriteLine("Your Answer is :" + x);
}
finally
{
Console.WriteLine("Finaly block execute");
}
}
}
/*Output:-
Enter the 'a' value: 9
Enter the 'b' value: 3
Unhandled Exception: DivideByOddNumberException: Attempted to divide by odd number.
at ExceptionHandle.Main()
Finaly block execute
*/
Here you see both error messages Unhandled Exception: DivideByOddNumberException:
and Unhandled Exception: System.ApplicationException:
in System
are present in the ApplicationException
error message, but nothing is there in the DivideByOddNumberException
error message. To fix that, use the namespace like this:
using System;
namespace MyNsp
{
public class DivideByOddNumberException: ApplicationException
{
public override string Message
{
get
{
return "Attempted to divide by odd number.";
}
}
}//End DivideByOddNumberException class
class ExceptionHandle
{
static void Main()
{
try
{
Console.Write("Enter the \'a\' value: ");
int a = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter the \'b' value: ");
int b= Convert.ToInt32(Console.ReadLine());
if(b%2 > 0)
{
throw new MyNsp.DivideByOddNumberException();
}
int x = a/b;
Console.WriteLine("Your Answer is :" + x);
}
finally
{
Console.WriteLine("Finaly block execute");
}
}
}
}
/*Output:-
Enter the 'a' value: 9
Enter the 'b' value: 3
Unhandled Exception: MyNsp.DivideByOddNumberException: Attempted to divide by odd number.
at MyNsp.ExceptionHandle.Main()
Finaly block execute
*/
File System: Managing Folders and Files
Stream is a flow of data from one direction to another. There are two types of Streams:
Input Stream
Output Stream
Input Stream is used to read from the user, whereas Output Stream is used to display data on the console.
File Stream is used to work with files, meaning writing data into files or reading data from files.
To work with File Streams in C#, we have to use the namespace called System.IO. The following classes are used to work with FileStreams in C#:
FileStream
StreamWriter
StreamReader
BinaryWriter
BinaryReader
FileInfo
DirectoryInfo
FileStream : It is a class which is used to open a file by specifying the name,path, mode and access.
Modes:
Create: to create a new file. If the file is already exists then it will overwritten.
CreateNew: to create a new file. If the file is already exists then it will raise an Exception.
Open: to open an existing file.
OpenOrCreate: If the file exists it will open otherwise it will create a new file.
Append: to add data to an existing file.
Truncate: to delete the contents of the file
Access:
Write: to create a new file and to write data into it.
Read: to read data from an existing file.
ReadWrite: used for both reading and writing.
Get all folders inside any folder:
using System;
using System.IO;
namespace FileStream
{
internal class Program
{
static void Main(string[] args)
{
string rootPath = @"D:\dotnet\Practice\FileStream";
//Get all folder in side the FileStream folder
string[] dirs = Directory.GetDirectories(rootPath);
foreach (string dir in dirs)
{
Console.WriteLine(dir);
}
}
}
}
/*Out:-
D:\dotnet\Practice\FileStream\All_example_file
D:\dotnet\Practice\FileStream\bin
D:\dotnet\Practice\FileStream\obj
D:\dotnet\Practice\FileStream\Properties
*/
Why do we use @"D:\dotnet\Practice\FileStream"? Because the @ symbol before a string literal creates a verbatim string.
What is verbatim string? Verbatim strings ignore escape sequences like \
and treat the backslash as a normal character. This is especially useful for file paths and regular expressions, where backslashes are often used.
Example without Verbatim String: "D:\dotnet\Practice\FileStream";
Example with Verbatim String: @"D:\dotnet\Practice\FileStream";
We get the same result using either without a Verbatim String or with a Verbatim String.
Directory.GetDirectories()
returns a string array.
Access the File and Folder/Directory:
Get all folders inside any folder/Directory with sub folder:
using System;
using System.IO;
internal class Program
{
static void Main(string[] args)
{
string rootPath = "D:\\dotnet\\Practice\\FileStream";
//Get all folder in side the FileStream folder
string[] dirs = Directory.GetDirectories(rootPath,"*",SearchOption.AllDirectories);
foreach (string dir in dirs)
{
Console.WriteLine(dir);
}
}
}
/*Out:-
D:\dotnet\Practice\FileStream\All_example_file
D:\dotnet\Practice\FileStream\bin
D:\dotnet\Practice\FileStream\obj
D:\dotnet\Practice\FileStream\Properties
D:\dotnet\Practice\FileStream\bin\Debug
D:\dotnet\Practice\FileStream\obj\Debug
D:\dotnet\Practice\FileStream\obj\Debug\TempPE
*/
Get all files inside any folder:
using System;
using System.IO;
internal class Program
{
static void Main(string[] args)
{
string rootPath = "D:\\dotnet\\Practice\\FileStream";
//Get all folder in side the FileStream folder
string[] dirs = Directory.GetFiles(rootPath,"*.*",SearchOption.TopDirectoryOnly);
foreach (string dir in dirs)
{
Console.WriteLine(dir);
}
}
}
/*Out:-
D:\dotnet\Practice\FileStream\App.config
D:\dotnet\Practice\FileStream\FileStream.csproj
D:\dotnet\Practice\FileStream\Program.cs
*/
Get all files inside any folder with subfolder files:
string[] dirs = Directory.GetFiles(rootPath,"*.*",SearchOption.AllDirectories);
/*Out:-
D:\dotnet\Practice\FileStream\App.config
D:\dotnet\Practice\FileStream\FileStream.csproj
D:\dotnet\Practice\FileStream\Program.cs
D:\dotnet\Practice\FileStream\bin\Debug\FileStream.exe
D:\dotnet\Practice\FileStream\bin\Debug\FileStream.exe.config
D:\dotnet\Practice\FileStream\bin\Debug\FileStream.pdb
D:\dotnet\Practice\FileStream\obj\Debug\.NETFramework,Version=v4.7.2.AssemblyAttributes.cs
D:\dotnet\Practice\FileStream\obj\Debug\DesignTimeResolveAssemblyReferencesInput.cache
D:\dotnet\Practice\FileStream\obj\Debug\FileStream.csproj.AssemblyReference.cache
D:\dotnet\Practice\FileStream\obj\Debug\FileStream.csproj.CoreCompileInputs.cache
D:\dotnet\Practice\FileStream\obj\Debug\FileStream.csproj.FileListAbsolute.txt
D:\dotnet\Practice\FileStream\obj\Debug\FileStream.exe
D:\dotnet\Practice\FileStream\obj\Debug\FileStream.pdb
D:\dotnet\Practice\FileStream\Properties\AssemblyInfo.cs
*/
Get all files inside any folder with subfolder/SubDirectory files without path:
string rootPath = @"D:\dotnet\Practice\FileStream";
//Get all folder in side the FileStream folder
string[] dirs = Directory.GetFiles(rootPath,"*.*",SearchOption.AllDirectories);
foreach (string dir in dirs)
{
Console.WriteLine(Path.GetFileName(dir));
}
/*Out:-
App.config
FileStream.csproj
Program.cs
FileStream.exe
FileStream.exe.config
FileStream.pdb
.NETFramework,Version=v4.7.2.AssemblyAttributes.cs
DesignTimeResolveAssemblyReferencesInput.cache
FileStream.csproj.AssemblyReference.cache
FileStream.csproj.CoreCompileInputs.cache
FileStream.csproj.FileListAbsolute.txt
FileStream.exe
FileStream.pdb
AssemblyInfo.cs
*/
More example:-
string rootPath = @"D:\dotnet\Practice\FileStream";
//Get all folder in side the FileStream folder
string[] dirs = Directory.GetFiles(rootPath,"*.*",SearchOption.AllDirectories);
foreach (string dir in dirs)
{
Console.WriteLine(Path.GetFileNameWithoutExtension(dir));//If you want to get the file name without the extension
Console.WriteLine(Path.GetFullPath(dir));//If you want to get the full path
Console.WriteLine(Path.GetDirectoryName(dir));//Get directry name
//Get file information:-
var info = new FileInfo(dir);
Console.WriteLine(info.Length);
Console.WriteLine($"{info.Length} bytes");
//ETC:-
}
Cheak folder/Directory exists or not:
string rootPath = @"D:\dotnet\Practice\FileStream";
//Cheak Folder exist or not
bool directoryExists = Directory.Exists(rootPath + "\\SubFolder");
Console.WriteLine(directoryExists);//Out: False
bool directoryExists2 = Directory.Exists(rootPath + "\\All_example_file");
Console.WriteLine(directoryExists2);//Out: True
Create Folder/Directory:
string rootPath = @"D:\dotnet\Practice\FileStream";
//Cheak Folder exist or not
bool directoryExists = Directory.Exists(rootPath + "\\SubFolder");
Console.WriteLine(directoryExists);//Out: False
if (!directoryExists)
{
Directory.CreateDirectory(rootPath + "\\SubFolder");
}
directoryExists = Directory.Exists(rootPath + "\\SubFolder");
Console.WriteLine(directoryExists);//Out: True
Copy the files and paste another folder:
string rootPath = @"D:\dotnet\Practice\FileStream";
string destany = @"D:\dotnet\Practice\FileStream\All_example_file\";
//copy-pest
string[] files = Directory.GetFiles(rootPath);
foreach (string file in files)
{
File.Copy(file, $"{destany}{Path.GetFileName(file)}", true);
//true use to not overwrite, false is to overwrite
}
Move files:
string rootPath = @"D:\dotnet\Practice\FileStream\All_example_file";
string destany = @"D:\dotnet\Practice\FileStream\SubFolder\";
string[] files = Directory.GetFiles(rootPath);
foreach (string file in files)
{
File.Move(file, $"{destany}{Path.GetFileName(file)}");
}
Get particullar extension named files:
string rootPath = @"D:\dotnet\Practice\FileStream\All_example_file";
var files = Directory.GetFiles(rootPath,"*.txt*",SearchOption.AllDirectories);
foreach (string file in files)
{
Console.WriteLine(file);
}
Search files using name:
string rootPath = @"D:\dotnet\Practice\FileStream\SubFolder";
var files = Directory.GetFiles(rootPath, "*testDemo*.*", SearchOption.AllDirectories);
foreach (string file in files)
{
Console.WriteLine(file);
}
Programs using FileStreams
Writing data into a new file
Appending data to an existing file
Reading data from an existing file
Deleting a file
Writing & Appending data into a new file:
string filePath = @"D:\dotnet\Practice\FileStream\All_example_file\testDemo.txt";
FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write);
//or Appending
//FileStream fs = new FileStream(filePath, FileMode.Append, FileAccess.Write);
StreamWriter writer = new StreamWriter(fs);
writer.Write("Hello World");
writer.Flush();
writer.Close();//CLose the file
fs.Close();//Close the FileStream
Reading data from an existing file:
string filePath = @"D:\dotnet\Practice\FileStream\All_example_file\testDemo.txt";
FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
StreamReader writer = new StreamReader(fs);
string data = writer.ReadLine();
Console.WriteLine(data);
writer.Close();
fs.Close();
Deleting a file:
string filePath = @"D:\dotnet\Practice\FileStream\All_example_file\testDemo.txt";
// Cheak file exist or not
if (File.Exists(filePath))
{
File.Delete(filePath); // Deleting the file
}
Deleting a folder:
string Path = @"D:\dotnet\Practice\FileStream\SubFolder";
// Cheak folder exist or not
if (Directory.Exists(Path))
{
//Delete folder
Directory.Delete(Path, true);// true for recursive deletion
}
Accept n value from user and ask for n students details and store it:
string filePath = @"D:\dotnet\Practice\FileStream\All_example_file\demo.txt";
FileStream fs = new FileStream(filePath, FileMode.CreateNew, FileAccess.Write);
StreamWriter writer = new StreamWriter(fs);
for (int i = 0; i < 3; i++)
{
Console.Write("Enter id: ");
int id = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter Name: ");
string name = Console.ReadLine();
//writer.Write($"id: {id}, name: {name}");
//or
writer.WriteLine($"id: {id}, name: {name}");
}
writer.Flush();
writer.Close();
fs.Close();
Read all students details from the file and display.
string filePath = @"D:\dotnet\Practice\FileStream\All_example_file\demo.txt";
FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
StreamReader writer = new StreamReader(fs);
//string data = writer.ReadLine();//Read only first line
string data = writer.ReadToEnd();//Read only first line
Console.WriteLine(data);
writer.Close();
fs.Close();
Writing Binary data into file and reading data from Binary file.
string filePath = @"D:\dotnet\Practice\FileStream\All_example_file\demo.txt";
//Write:-
FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Write);
BinaryWriter writer = new BinaryWriter(fs);
int a = 47;
string b = "Mritunjay";
double c = 12.45;
writer.Write(a);
writer.Write(b);
writer.Write(c);
writer.Flush();
writer.Close();
fs.Close();
//Read:-
FileStream fsr = new FileStream(filePath, FileMode.Open, FileAccess.Read);
BinaryReader read = new BinaryReader(fsr);
Console.WriteLine(read.ReadInt32());//Out:- 47
Console.WriteLine(read.ReadString());//Out:- Mritunjay
Console.WriteLine(read.ReadDouble());//Out:- 12.45
read.Close();
fsr.Close();
You've successfully completed the basics of C# programming!. These fundamentals are crucial for building more complex and efficient applications.
Next Steps:
To advance your C# skills, consider exploring these topics:
Object-Oriented Programming (OOP)
LINQ (Language Integrated Query)
Asynchronous Programming
Advanced Data Structures
Design Patterns
Recommended Blog for Advanced Learning:
Check out the Learn C#.NET Advancec Level tutorials and resources on advanced C# programming. Happy coding!.