[go: up one dir, main page]

0% found this document useful (0 votes)
11 views88 pages

C Sharp Complete Guide

C# is an object-oriented programming language developed by Microsoft, closely related to C++ and Java, used for various application development. The document covers C# fundamentals, including data types, control flow, object-oriented programming principles, and advanced topics like collections and asynchronous programming. It also provides guidance on setting up the development environment and creating projects using Visual Studio and VS Code.

Uploaded by

Kareem Mohamed
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views88 pages

C Sharp Complete Guide

C# is an object-oriented programming language developed by Microsoft, closely related to C++ and Java, used for various application development. The document covers C# fundamentals, including data types, control flow, object-oriented programming principles, and advanced topics like collections and asynchronous programming. It also provides guidance on setting up the development environment and creating projects using Visual Studio and VS Code.

Uploaded by

Kareem Mohamed
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 88

C# Programming Language

Definition: It’s an object-oriented programming language created by


Microsoft, C# has root from the C family, and the language is close to
other popular language like C++ & Java, used for develop (Mobile ,
Desktop, Web, Web Services, and more..)

C# Basics Fundamental
Get Started Composed Data
Preparing Work Array
Environment Arrays Definition
Install IDE (VS Code || Visual Arrays Method
Studio)
2 Dimensional Array
Creating your first project
Lists
Variables & Data Type Lists Definition
Types Of Data Type Declaring And Get List
Value Data Type Lists Methods
Reference Data Type
Dictionary
Type Casting Declaring Dictionary
Implicit Casting Get Dictionary Value

C# Programming Language 1
Explicit Casting Functions
Parse Method Functions Definitions And
Mathematic Operator Types
Addition Functions

Subtraction Void functions

Division Return type functions

Multiplication Parameters (Arguments)


Reminder Function parameters

Increment Named parameters

Decrement Optional parameters

Math Static Class Reference parameters

Keywords Inner parameters

Var keyword Outer parameters

Const keyword
Errors Handling
Control Flow Errors
Conditions Syntax Error

If statements Logic Error

Switch statements Exceptions


Loops Handle Exception (try / catch)

For loop Exception Class

While loop Built-in Exception

Do While loop Custom Exception

Exception Filter
String Syntax
Swallow & Duck Exception
Path Value Into String
String concatenation Debugging
String formatting ({0}) Debugging Mode
Numeric formatting

C# Programming Language 2
String interpolation ($) Set a breakpoint and start
debugging
Verbatim string literal (@)
String Methods Principles of defensive
programming
Empty string
Local/auto window
String Equals function
Watch window
String IsNullOrEmpty function

String iteration looping

C# Intermediate
OOP (Object Oriented Advanced OOP Keywords
Programming) Principles Interfaces
Classes & Objects Interfaces
Class Member
Explicit interface implementation
Constructor
Classes Other Type
Extension Methods
Structures
Access Modifiers Enumeration
Public
Important Keywords
Private
Static Keyword
Internal
Namespaces Keyword
Protected
Project Structure
OOP Principles Concept
Files I / O Library
Inheritance
Stream (Reader & Writer) Class
Encapsulation
File Class
Polymorphism

Abstraction

Method Hiding & Shadowing

Relationships Between
Classes

C# Programming Language 3
Association (Use a..)

Aggregation (Has a..)

Composition (Owns a..)

Practice OOP
Tutorial Project (With Video) Exercise Project (No Video)
🏦 Design A Simple System Bank (Read 📒 Contact Manager
Only)

📚 Library Management System


🎮 Maze Game
📈 Text Data Analyzer
C# Advanced
Collections Advanced C# v.2 - v.3
Generics Delegates & Lamda
Generics Definition Delegates

Generics Class Anonymous Method & Lamda


Expressions
Generics Methods
Delegates Chains
Generics Interface
Generics Delegates
Generics Constrains
Func, Action And Predicate
Collections in C#
Generics Collection
Events
Events & Observer pattern
Non-Generics Collection
Event Handler & Event Args
Array Lists

Stack & Queue Covariance & Contra-


Variance

C# Programming Language 4
Tuples Covariance
Key Value Per Collections Contra-variance
Sorted List

Hash Table Asynchronous


Programming
Collection Internal
Threading
IEnumerable

IEnumerator

Indexers Others
Collections Exercise - Partial Class
Shopping System Project Partial Method

🛒 Shopping System Project Finalizer

Nested Type

Basics Fundamental
Get Started
Preparing Work Environment
An integrated development environment (IDE) is software application that helps
programmers develop software code efficiently.

Best IDE to develop software using C# language is:

Visual Studio 2022

VS Code

Creating First Project With C#


With Visual Studio 2022

open visual studio and click create a new project.

chose console app (work for all platform, Mac, Windows, Linux) or console app (.NET
framework) (work for windows only).

C# Programming Language 5
check “Do not use top-level statements” if you want old format of C#. (Not a big deal)

click run button on top bar menu (CTRL + F5) to run your project.

With VS Code (.NET CLI)

Install this extensions to your VS Code

C# Dev Kit

create new folder on your PC

open folder path using your terminal

create new solution using this command

dotnet new sln

create new console project using this command

dotnet new console -n ProjectName

add your project to your solution using this command

dotnet sln add ProjectName

go to your project path in terminal then use this command to run project

dotnet run

open your project with VS Code and start coding 😊


Variables And Datatype
Variable are containers for storing data values.
in C#, there are different types of variables (defined with different keyword)

Declaring Variables
to create variable, you have to specify the type and assign it a value.

// type variableName = value;

C# Programming Language 6
string Name = "Medhat";

Type of Datatype
1. Value Datatype: directly store the variable value in memory and it will also accept both
signed and unsigned literals

2. Reference Datatype: contain a memory address of variable value because reference type
won’t store the value directly in memory

Datatype Description Type

int Store number (4 byte) Example: 42 Numeric Datatype

float Store number (4 byte) Example: 10.23 Numeric Datatype

double Store number (8 byte) Example: 231.2313 Numeric Datatype

decimal Store number (16 byte) Example: 1413.445.2123 Numeric Datatype

char Store character (16 byte) Example: ‘F’ Text based Datatype

string Store Collection of character, Example “Nemo” Text based Datatype

bool Store 1 : 0 (True : False) Boolean Datatype

Example:

int number = 10;


double doubleNumber = 3123.3123d;
float floatNumber = 32.41f;
decimal decimalNumber = 321.413m;
Console.WriteLine($"Numerical Datatype: {number} - {doubleNum
string text = "someText";
char character = 'L';
Console.WriteLine($"Text Base Datatype: {text} - {character}"

Type Casting
when you assign a value of one datatype to another type.
there are tow types of casting

1. Implicit Casting

2. Explicit Casting

Implicit Casting (Automatically): Convert a smaller type to a larger type size.

C# Programming Language 7
// char -> int -> long -> float -> double
int smallType = 20;
double largeType = smallType; // Automatic Casting
Console.WriteLine(largeType);

Explicit Casting (Manually): Converting a larger type to a smaller size type.

// double -> float -> long -> int -> char


double largerType = 40.32; // Convert it to int
int smallerType;
// Solution One
smallerType = (int)largerType;
// Solution Two
smallerType = Convert.ToInt32(largerType);

Parse Method : Help you to handle error if casting fail at runtime by


using int.TryParse() this function take two arguments first one is value
you want to cast it, second one is outer parameter that value will store in
it if casting success at runtime

// Solution Three Of Convert it to int question


string textType = "10";
int Number;
if (int.TryParse(textType, out Number))
{
smallerType = Number; // assign the parsed value to smallerTy
}

Mathematic Operator
Operation Symbol Example

Addition + x = x + y;

Subtraction - x = y - x;

Division / x = y / x;

Multiplication * x = y * x;

C# Programming Language 8
Operation Symbol Example

Reminder % x = y % x;

x++ Get Value then Increment


increment ++ ++
y Increment then Get Value

x-- Get Value then Decrement


Decrement --
--y Decrement then Get Value

Math Class: Have many methods that allows you to perform


mathematical tasks on methods.

Example:

Math.Max(5, 10); // The Math.Max(x,y) method can be used to fi


Math.Min(5, 10); // The Math.Min(x,y) method can be used to fi
Math.Sqrt(64); // The Math.Sqrt(x) method returns the square
Math.Abs(-4.7); // The Math.Abs(x) method returns the absolute
Math.Round(9.99); // Math.Round() rounds a number to the neare

Keywords
are the words in a language that are used for some internal process or represent some
predefined actions.

Var Keyword
is a keyword, it’s used to declare and implicit type variable, that specifies the type of
variables based on initial value.

var variable = "Text"; // variable is string


var variable = 20; // variable is int

Const Keyword
if you don’t want others (or yourself) to overwrite value, you can add the const keyword
in front of the variable type.

const float PI = 14.3f;

C# Programming Language 9
//PI = 13.2; // Error Becuse you can't overwrite a constan

Control Flow
Conditional Statement
specify a block of C# code to be executed if a condition is true.

Conditions

Condition Symbol Example

Less Than < x < y

Less Than Or Equal <= x <= y

Greater Than > x > y

Greater Than Or Equal >= x >= y

Equal To == x == y

Not Equal To != x != y

Multiply Conditions

Definitions Symbol Rule

AND (Executable while condition not


&& true && true
success)

OR (Executable while condition not true || false or flase ||


||
success) true

!true = false or !false =


NOT !
true

true ^ true = false

true ^ false = true


XOR ^
false ^ true = true

false ^ false = false

AND (Executable All Condition) & false & true

OR (Executable All Condition) | true | false

1. If Statement

C# Programming Language 10
int x = 10, y = 20;
if (x < y)
{
Console.WriteLine($"x:{x} is less than y:{y}");
}
else if (x == y)
{
Console.WriteLine($"x:{x} is equal y:{y}");
}
else
{
Console.WriteLine($"x:{x} is grater than y:{y}");
}

2. Switch Statement

int x = 2;

switch (x)
{
case 2:
Console.WriteLine("x = 2");
break;
case 5:
Console.WriteLine("x = 5");
break;
case 10:
Console.WriteLine("x = 10");
break;
default:
{
Console.WriteLine("No Conditon Role Success");
break;
}

C# Programming Language 11
Loop Statements
For Loop: When you know exactly how many times you want to loop through a block of
code.

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


{
Console.WriteLine(i);
}

While Loop: Loops can executed a block of code. as long as a specified condition is
true.

int j = 10;
while (j != 0)
{
Console.WriteLine(j);
j--;
}

Do While Loop: This loop will execute the code block once, before checking if
condition is true or not.

do
{
Console.WriteLine(2);
} while (3 > 4);

String Syntax
Path Value Into String
String Concatenation

concatenate strings to each other use + symbol

Console.WriteLine("My Name is" + " Medhat" + " Assem");

String formatting

C# Programming Language 12
use to path a value into string without concatenation symbol

string Name = "Medhat";


int Age = 25;
Console.WriteLine("Hello my name is {0} my age is {1}", Nam

Numeric formatting

used to format common numeric type

double Numeric = 81.0372771474878D;


Console.WriteLine(string.Format("{0}", Numeric)); // Normal
Console.WriteLine(string.Format("{0:0.00}", Numeric)); // 8
Console.WriteLine(string.Format("{0:0.0}", Numeric)); // 81
Console.WriteLine(string.Format("{0:0}", Numeric)); // 81
// if # represent number equal to zero it will n't display
Console.WriteLine(string.Format("{0:0.#}", Numeric));

Currency Format

Some method to show currency beside the value

ToString(”C”) get currency of your culture

“C0” Normal Value

“C1” Display First Decimal number

“C2” Display Two Decimal number only

decimal money = 21.23M;

Console.WriteLine(money.ToString("C")); // equal to
Console.WriteLine(money.ToString("C1"));
Console.WriteLine(money.ToString("C2"));

CultureInfo Class: To specify which culture currency you want it to display


using this method:

CultureInfo.CurrentCulture()

CultureInfo.CreateSpecificCulture("en-GB") England Currency, Use this


Link to get more culture currency string info CultureInfo Class Doc

C# Programming Language 13
deciaml money = 46.89M;

Console.WriteLine(money.ToString("C", CultureInfo.Cu
Console.WriteLine(money.ToString("C",
CultureInfo.CreateSpecificCulture("en-us")));

String Interpolation

concatenate strings to each other use $ symbol

string Name = "Medhat";


int Age = 25;
Console.WriteLine($"My Name is {Name} and my age is {Age}"

Verbatim string literal

To indicate that string literal is to be interpreted verbatim

Console.WriteLine(@"My Name is Medhat


And my Age is 25
Email: /* MedhatAssm@gmail.com */");
// Output
// My Name is Medhat
// And my Age is 25
// Email: /* MedhatAssm@gmail.com */

String Methods
string.Empty

it used to represent Empty quotation mark “” , in clean code you should make your code
readable for any one work on project after you so let’s ask you which is better and
understandable easier:

if(Name == ""){ if(Name == string.Empty){

// Block of code // Block of Code

C# Programming Language 14
} }

This Up to you but best practice try use string.Empty() more in


your project.
string.Equals

it used to represent == symbol like string.Empty for clean code and make your code
more readable for other programmer.

if(Name.Equals("Medht")){ if(Name == "Medhat"){

// Block of code // Block of Code

} }

Also up to you to chose but which is better for read do you think ?

string.IsNullOrEmpty
it is used to check whether the specified string is null or and empty string. A string will
be Null if it hasn’t been assigned value

if (string.IsNullOrEmpty(Name))
{

// Block of code

String Iteration looping

String is Array of Characters

treat your string as array with characters type so you can loop on it write loop statement
and you can search on it for specify characters using .Contain() method that return bool

C# Programming Language 15
type and with .IndexOf() method that return address of your characters and now you can
get it easily.

string txt = "Hello My Name is Medhat Assem And this Simpal

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


{
Console.Write(txt[i]);
Thread.Sleep(150); // That line make compiler stop For
}

Composed Data
Arrays
Array Definition

Array
its reference datatype, used to store multiple values in a single variables, instead of
declaring separate variables for each value.

To declare array

string[] arr = new string[];

To initialize value to array

// First Way:
string[] arrOfName = { "Ahmed", "Medhat", "Samier" };

// Second Way:
string[] arr = new string[];
stringArr[0] = "Medhat";
stringArr[1] = "Samier";

Get array value

Get single value

C# Programming Language 16
stringArr[0] = "Medhat";
stringArr[1] = "Samier";

Console.WriteLine(stringArr[0]);
Console.WriteLine(stringArr[1]);

Get all array data (Using Foreach)

string[] arrOfName = { "Ahmed", "Medhat", "Samier" };

foreach (var item in arrOfName)


{
Console.WriteLine(item);
}

Get all array data (Using Index)

string[] arrOfName = { "Ahmed", "Medhat", "Samier" };

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


{
Console.WriteLine(arrOfName[i]);
}

Array Methods

Array sorting

sorts an array alphabetically or in an ascending order.

// Sort a string
string[] cars = {"Volvo", "BMW", "Ford", "Mazda"};
Array.Sort(cars);
foreach (string i in cars)
{
Console.WriteLine(i);
}

// Sort an int

C# Programming Language 17
int[] myNumbers = {5, 1, 8, 9};
Array.Sort(myNumbers);
foreach (int i in myNumbers)
{
Console.WriteLine(i);
}

Array reversal

reverses the sequence of a subset of the elements in a one-dimensional array.

string[] spamLetters = {"S", "P", "A", "M"};

Array.Reverse(spamLetters);

Array clearing
used to clear the contents of an array, returning each element to its default value.

int[] myArray = {0, 1, 2, 3, 4};

Array.Clear(myArray, 0, myArray.Length);

Array IndexOf
searches for the specified object and returns the index of the first occurrence within
the entire one-dimensional Array.

int[] arr = { 100, 200, 300, 400, 500, 600, 700, 800, 90

int a = Array.IndexOf(arr, 800);

2 Dimensional Array

if you want to store data as a tabular form, like a table with rows and columns, you need
to get familiar with multidimensional arrays.

Array can have any number of dimensions. the most common are
two-dimensional array (2D)

Create 2D Array

C# Programming Language 18
int[,] numbers = { {1, 4, 2}, {3, 6, 8} };

Column 0 Column 1 Column 2

Row 0 1 4 2

Row 1 3 6 8

2D Array Access Element

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


Console.WriteLine(numbers[0, 2]); // Outputs 2

2D Array Change Elements

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


numbers[0, 0] = 5; // Change value to 5
Console.WriteLine(numbers[0, 0]); // Outputs 5 instead of 1

Loop Through a 2D Array

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

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


{
for (int j = 0; j < numbers.GetLength(1); j++)
{
Console.WriteLine(numbers[i, j]);
}
}

Lists
Lists Definition
to create a collection of different types like integers, strings etc. List<T> class also
provides the methods to search, sort, and manipulate lists.

C# Programming Language 19
It is different from the arrays. A List<T> can be resized
dynamically, can accept null as valid value for reference type, also
allows duplicate element.
Declaring And Get List

List<int> firstlist = new List<int>() { 1, 2, 3, 4 };

firstlist.Add(5);
firstlist.Add(6);
firstlist.Add(7);

foreach (var i in firstlist)


{
Console.WriteLine(i);
}

Lists Methods

Method Definition Example

Gets or sets the total number of


Console.WriteLine("Capacity
Capacity elements the internal data structure can Is: " + firstlist.Capacity);
hold without resizing.

Gets the number of elements contained Console.WriteLine("Count Is: "


Count + firstlist.Count);
in the List<T>.

Sorts the elements or a portion of the


elements in the List<T> using either the
specified or default IComparer<T>
Sort firstlist.Sort();
implementation or a provided
Comparison<T> delegate to compare
list elements.

Reverses the order of the elements in


Reverse firstlist.Reverse();
the List<T> or a portion of it.

Gets or sets the element at the specified Console.WriteLine("Item Is:" +


listName[index] firstlist[2]);
index.

Adds an object to the end of the


Add firstlist.Add(6);
List<T>.

AddRange Adds the elements of the specified firstlist.AddRange(firstlist);

C# Programming Language 20
Method Definition Example
collection to the end of the List<T>.

Returns a read-only
IList< int > readlist =
AsReadOnly ReadOnlyCollection<T> wrapper for firstlist.AsReadOnly();
the current collection.

Uses a binary search algorithm to locate int index =


BinarySearch a specific element in the sorted List<T> firstlist.BinarySearch(7);
or a portion of it. Console.WriteLine(index);

Removes all elements from the


Clear firstlist.Clear();
List<T>.

Determines whether an element is in bool isContain =


Contains firstlist.Contains(4));
the List<T>.

Dictionary
used to store key/value pairs, the advantage of Dictionary is, it is generic type, it is dynamic
in nature means the size of the dictionary is growing according to the need.

its like lists but you have unique key to each element so you can’t
access element without this key

Declaring Dictionary

Dictionary<int, string> dictionary = new Dictionary<int, s


{1,"Medhat"} ,
{2, "Ahmed"}
};

Get Dictionary value

Get single element

Dictionary<int, string> dictionary = new Dictionary<in


{1,"Medhat"} ,
{2, "Ahmed"}
};

Console.WriteLine(dictionary[1]); //[Key] not index

C# Programming Language 21
Get all data in dictionary

Dictionary<int, string> dictionary = new Dictionary<int


{1,"Medhat"} ,
{2, "Ahmed"}
};

foreach (KeyValuePair<int, string> item in dictionary)


{
Console.WriteLine(item.Key);
Console.WriteLine(item.Value);
}

Functions (Methods)
Functions Definitions And Types
is a block of code which only runs when its called, can return any datatype you want, used to
perform certain actions and to reuse code (define the code once, use it many time).

Create Function

/// Using Static keyword here becuse we in Entery point of


///
/// Void mean retrun Nothing.
public static void MethodName()
{
// Block of Code
}

Types of return

Can be any datatype.

// Main Method (Entery Point)


static void Main(string[] args)
{
// Call Methods
Console.WriteLine(GetName()); // My Name

C# Programming Language 22
Console.WriteLine(GetSum()); // 3
}
// Return string
public static string GetName()
{
return "My Name";
}

// Return Integer
public static int GetSum()
{
return 1 + 2;
}

Parameters (Arguments)
you can pass data, know as arguments, into method and used it in your code of function.

Parameters call to variables that declaring in method like this (string

name, int age) , Arguments call to variables that passing to method like
this MyMethod(MyName,MyAge) , its not a big different and call it whatever
you want but just in case you need to know the different of naming.

static void Main(string[] args)


{
// Passing Argument to Function
GetMyName("Medhat");
}
// Function With Parameter
public static string GetMyName(string myName)
{
return myName;
}

You can make (user / developer) add dynamic length of parameter as


array so make function take as many as argument it want .

C# Programming Language 23
static void Main(string[] args)
{
Equation(5 , 4 , 3 , 8, 9 , 10 , 2); //
}

// Dynamic Parameters
public static int Equation(int x, int y, params
{
int total = 0;
foreach (int i in arr)
{
total += i;
}

return x + y + total;
}

Named Parameters
You can path value to function using the name of variable not order in method.

static void Main(string[] args)


{
//Named Arguments
GetText(text1: "Hello", text2: "Welcome to C# Guide");
}

public static string GetText(string text1, string text2)


{
return text1 + "\n" + text2;
}

Optional Parameters

C# Programming Language 24
you can use optional parameters by initialize variable while define it, and that make this
parameter is optional, if (developer / user) not (insert / initialize) it with any value, it will
use the default value of it.

static void Main(string[] args)


{
//Optional Parameters
Sum(4); // 4 + 5 = 9
Sum(4 , 2); // 4 + 2 = 6
}

public static int Sum(int x, int y = 5)


{
return x + y;
}

Reference Parameters
ref is used to state that the parameter passed my be modified y the method.

static void Main(string[] args)


{
//Reference Parameters
string Name = "Ahmed";
bool isActive = true;
StudentInfo(ref Name , ref isActive);
Console.WriteLine(Name + "\n" + isActive); // Name = Me
}

Reference Parameter is tell the compiler that variable using inside


the method i will use it outside the method.

Inner Parameters

in is used to state that the parameters passed can’t modified by the method.

static void Main(string[] args)


{

C# Programming Language 25
//Inner Method
bool isEnrolled = false;
Enroll(isEnrolled);
}

public static void Enroll(in bool isEnrolled)


{
// Syntax Error That Variable Can't modify
// inside method because its inner parameter
// isEnrolled = true;
}

Outer Parameters
out is used to state that the parameter passed must be modified by method, sam as
reference but can’t leave variable without modify it in method.

static void Main(string[] args)


{
//Outer Method
string name = "Mostafa";
bool isactive = false;
Studentinfo(out name, out isactive);
Console.WriteLine(name + "\n" + isactive); // name = Al
}

public static void Studentinfo(out string Name, out bool is


{
Name = "Ali";
isAvtive = true;
}

Error Handling
Error
Syntax Error

C# Programming Language 26
an error in the syntax of a sequence of characters that is intended to be written in a
particular programming language

Logic Error
ones where you don’t get the result were excepting, you wan’t see any red color wavy
line, and the Program generally won’t “but out” on you, in other words, you have made
an error in your programming logic (show at run time).

Exceptions
Handle Exception (Try / Catch)
the try statement allow you to define a block of code to be tested for errors while its
being executed.
the catch statement allows you to define a block of code to be executed, if an error
occurs in the try block.

The try and catch keywords come in pairs.

Without using Try Catch

string number = "10.34MD";


int cast;

cast = Convert.ToInt32(number);

Using Try Catch

string number = "10.34MD";


int cast;

C# Programming Language 27
try
{
cast = Convert.ToInt32(number);
}
catch
{
Console.WriteLine("Invaid Cast");
}

Exception Class
using exception class as base class for which exception inherit to represent an error.

string number = "10.34MD";


int cast;

try
{
cast = Convert.ToInt32(number);
}
catch (InvalidCastException ex)
{
Console.WriteLine(ex.Message);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}

Built-in Exception

C# .Net includes built-in exception classes for every possible error, the exception class is
the base of all the exception classes.

C# Programming Language 28
Custom Exception
create a custom exception for user-defined exception.

using System;

public class EmployeeListNotFoundException : Exception


{
public EmployeeListNotFoundException()
{
}

public EmployeeListNotFoundException(string message)


: base(message)
{
}

public EmployeeListNotFoundException(string message, Ex


: base(message, inner)
{
}
}

Exception Filter
used it based on requirement you define for the exception, these handlers use the catch
statement with the when keyword.

C# Programming Language 29
try
{
//block of code
}
catch (Exception ex) when (ex.Message.Contains("404"))
{
//block of code
}

Swallow & Duck Exception

Swallow Exception : The practice of Ducking Exception : Avoiding your code


catching an error or exception, and then from getting hit by any exception
continuing without logging, processing, or
reporting the error to other parts of the
software.

Debugging
Debugging Mode
Set a breakpoint and start debugging

1. In the C# project, open Program.cs.

2. Press F5, select the green arrow in the Visual Studio toolbar, or select Debug > Start
Debugging to start debugging. The debugger pauses on the breakpoint that you set.

Principles of defensive programming

Writing robust and reliable code is paramount for all software developers. However, no
matter how careful we are, bugs and unexpected situations can still occur. This is where

C# Programming Language 30
defensive programming comes into play. Defensive programming is a coding practice
aimed at ensuring that software functions correctly even when unexpected events or
invalid inputs occur.

1. Validate Input
Always validate input data to ensure that it meets the expected criteria before
processing it. This helps prevent runtime errors and ensures the stability of the
application.

2. Handle Exceptions
Anticipate potential failure points in your code and use exception handling
mechanisms such as try-catch blocks to gracefully handle errors and prevent crashes.

3. Fail Fast
Identify and report errors as soon as they occur rather than allowing them to
propagate through the system. This helps in pinpointing issues early in the
development process.

4. Use Assertions
Incorporate assertions into your code to enforce assumptions about the program’s
state. Assertions can help detect logical errors early during development and testing
phases.

5. Avoid Mutable State

Minimize the use of mutable state and prefer immutable data structures wherever
possible (see also “Understanding Mutable and Immutable Types in C#”). This
reduces the risk of unintended side effects and makes the code easier to reason
about.

6. Encapsulate Complexity
Encapsulate complex logic and dependencies within well-defined modules or
classes. This promotes modularity and reduces the likelihood of unintended
interactions between different parts of the codebase.

Local/auto window

The Autos window shows variables used The Locals window shows variables
around the current statement where the defined in the local scope, which is
debugger is paused. usually the current function or method.

C# Programming Language 31
Watch window
While you're debugging, you can use Watch windows and QuickWatch to watch
variables and expressions. The windows are only available during a debugging session.

Intermediate
Object Oriented Programming Principles (OOP)

OOP enable developers to think in terms of object, classes and method,


making code more intuitive and easier to maintain.

Classes & Objects


class and object are tow main aspect of OOP, So a class is a template for object, and object is
an instance of a class like image below.

Class Members

C# Programming Language 32
Variables inside a class called Fields, and that you can access them by create an object of
the class.

Variables (Properties) Description of Class Properties

Method (Behavior) Description of Class Behavior (What it can do!)

public class Car


{
public string _type = "Nissan";
public string _color = "Red";
public double _kmh = 50000;

public string MoverForword()


{
return "Car Moved forword.";
}
}

Class Constructors
is a special method that is used to initialize object.
The Advantage of a constructors:

That its called when an object of a class created.

it can be used to set initial values for fields.

class Car{ class Program{

public string model; Car car = new Car();


Console.WriteLine(ca
public Car()
{ }
model = "Nissan"
}

C# Programming Language 33
class Car{ class Program{

public string model; Car car = new Car("V

public Car(string Mo }
{
model = Model;
}

Constructor Chaining
a technique in C# that allow one constructor to call another constructor of the same class
or a class base (parent)

// First Constructo
public Car() : this("Volvo")
{
model = "Nissan";
}

// Second Constructor
public Car(string Model)
{
model = Model;
}

Car car = new Car();


Console.WriteLine(car.model); // "Nissan"

Extension Method

allows you to add new methods in the existing class or in the structure without
modifying the source code of the original type.

The child class that have method you add have to be static.

C# Programming Language 34
public class ExtensionMethod static public class Extensio
{ {
public void SayHello() public static void SayWe
{ {
Console.WriteLine("He Console.WriteLine("H
} }

public void SayWelcome() }


{
Console.WriteLine("We
ExtensionMethodParent extens
}
}
extensionMethod.SayHello();
extensionMethod.SayWelcome()
Now you can Call extensionMethod.SayWelcomeAn

SayWelcomeAndHello
Function with
ExtensionMethodParent
instant object in your entry point
(Main).

Access Modifiers
Public → The Code is accessible for all classes

Private → The Code is only accessible within the same class

if you didn’t declare any access modifiers compiler will use Private
as default one.

Internal → The Code is only accessible within its own assembly (DLL Folder), but not
from another assembly(DLL Folder)

Protected → The Code is accessible within the same class, or in a class that inherited
from it

C# Programming Language 35
OOP Principles Concept

Inheritance
inherit fields and methods from one class to another,
inheritance concept into two category:

Derived Class (Child) : that class that inherits from


another class

Base Class (Parent) : that class being inherited from.

To inherit use : symbol between


classes.

public class AnimalBaseClass


{
public string? Name { get; set; }
public int Wight { get; set; }

public AnimalBaseClass(string Name, int Wight)


{
this.Name = Name;
this.Wight = Wight;
}

public virtual void Eat()


{
Console.WriteLine($"{Name} Is Eating");
}
}

Virtual Keyword
The virtual keyword is used to modify a method, property, indexer, or event declaration
and allow for it to be overridden in a derived class.

Override Keyword

C# Programming Language 36
in Derived Class (Child) using override keyword to tell the compiler that this method
will be override from original one in parent class (Base Class).

class DogDrivedClass : Animal class CatDrivedClass : Anima


{ {
public DogDrivedClass(st public CatDrivedClass(st
{ {
Console.WriteLine("Do Console.WriteLine("C
} }
public void Barking() public void Mewo()
{ {
Console.WriteLine("Wo Console.WriteLine("M
} }
public override void Eat
// public override void {
// { Console.WriteLine("C
// Console.WriteLine( }
// } }
}

DogDrivedClass newDog = new DogDrivedClass("Max", 64); /* Dog


=> The

// AnimalBaseClass newDog = new DogDrivedClass("Max", 64);

Console.WriteLine(newDog.Name); // Get Name From Base Class Va


newDog.Eat(); // Using Eat method that is in base class becau
newDog.Barking(); // normal method.

CatDrivedClass newCat = new CatDrivedClass("Bussy", 20);


newCat.Eat(); // Using Eat method in cat class because its ov
newCat.Mewo();

Sealed Keyword : That Prevent class to inherit from a class

// Parent (Sealed)
sealed class AnimalMoreInfo

C# Programming Language 37
{
public AnimalMoreInfo()
{
Console.WriteLine("This is Fantasi Animal");
}
}

// Child (Can't inherit from parent)


class Unicon // : AnimalMoreInfo //! Error: 'Unicon': canno
{
public Unicon()
{

}
}

Encapsulation (Properties)

is to make sure that “Sensitive” data is hidden from user to access them you have to:
provide (get & set) method. through properties to access and update the value of private
field.

class Person
{
private string? _name;
public string? Name
{
get
{
// Logic
if (_name != "No Name")
{
return _name;
}
else
{
return "No Name Entered Please ReEnter you
}
}

C# Programming Language 38
set
{
// Logic
_name = !string.IsNullOrEmpty(value) ? value :
}
}

// Smart Properties
public int Age { get; /* set; */} = 25;
}

Smart Properties: in C# you can create encapsulation properties in one line, if you
not need a logic code to set or get that variable, you can just control of read and
write of variable if you use smart properties to control it.

Person person = new Person();


person.Name = "Medhat"; // Set
Console.WriteLine(person.Name); // Get
// person.Age = 25; //! Error Read only field.
Console.WriteLine(person.Age);

Advanced of Using Encapsulation :

Better control of class members

Fields can be made read only, write only.

Flexible: the programmer can change one part of the code


without affecting other parts Increased security of data.

Polymorphism

means “Many Forms”, and it occurs when we have many classes that are related to each
other by inheritance.
it is useful for code reusability: reuse fields and methods of an existing class when you
create a new class.

C# Programming Language 39
// Dynamic Polymorphism (RunTime Polymorphism), Interface,
class Monster // Base Class
{
public virtual void MakeSound()
{
Console.WriteLine("Monster Make Sound");
}
}

class Lion : Monster


{
public override void MakeSound()
{
Console.WriteLine("Lion Make Sound");
}
}

class Tiger : Monster


{
public override void MakeSound()
{
Console.WriteLine("Tiger Make Sound");
}
}

// Static Polymorphism (Method Overrloading) (Combile Time

class Calculator
{
public int Add(int a, int b)
{
return a + b;
}

public int Add(int a, params int[] arr)


{
int total = 0;
foreach (var item in arr)

C# Programming Language 40
{
total += item;
}

return total + a;
}
}

Monster lion = new Lion();


lion.MakeSound();
Monster tiger = new Tiger();
tiger.MakeSound();

Calculator c = new Calculator();


Console.WriteLine(c.Add(2, 2));
Console.WriteLine(c.Add(5, [2, 2, 1]));

Abstraction

is the process of hiding certain details and showing only essential information to the user.

it is not possible to create an object of abstract class.

to access abstract class, it must be inherited from another class.

using abstraction to achieve security in your code.

abstract class Shop // Can't create instance object from a


{
public abstract void Open();

// Concrete
public void Close()
{
Console.WriteLine("Shop Closing");
}
}

class ClothingShop : Shop


{

C# Programming Language 41
public override void Open()
{
Console.WriteLine("Clothing Shop Open");
}
}

class EatingShop : Shop


{
public override void Open()
{
Console.WriteLine("Eating Shop Open");
}
}

ClothingShop clothingShop = new ClothingShop();


clothingShop.Open();
clothingShop.Close();
EatingShop eatingShop = new EatingShop();
eatingShop.Open();
eatingShop.Close();

Method Hiding & Shadowing

Hiding Method: it’s a concept of Polymorphism, but what if you want not to use
the override method and want your object yo use base method from parent class And
that what Hiding Method do.

When using hiding method, don’t use override keyword use


new keyword.

public class Animal // Base Class


{
public virtual void MakeSound()
{
Console.WriteLine("Animal makes a sound.");
}
}

C# Programming Language 42
public class Cat : Animal // Child Class
{
public new void MakeSound() // new keyword use to ac
{
Console.WriteLine("Cat makes a sound.");
}
}

// Method Hiding
Animal animal1 = new Animal();
Animal cat1 = new Cat();
// Cat animal2 = new Animal(); // Compilation error - ca
Cat cat2 = new Cat();

animal1.MakeSound(); // Output: "Animal makes a sound."


cat1.MakeSound(); // Output: "Animal makes a sound."
cat2.MakeSound(); // Output: "Cat makes a sound."

Shadowing Method: Same as Hiding Method but without using polymorphism it


will just act like Hiding Method, this can lead to unexpected behavior as the base
class method may still be invoked when calling the method on an object of the
derived class.

public class Animal // Base Class


{
public void MakeSound()
{
Console.WriteLine("Animal makes a sound.");
}
}

public class Cat : Animal // Child Class


{
public void MakeSound()
{
Console.WriteLine("Cat makes a sound.");

C# Programming Language 43
}
}

// Method Hiding
Animal animal1 = new Animal();
Animal cat1 = new Cat();
// Cat animal2 = new Animal(); // Compilation error - ca
Cat cat2 = new Cat();

animal1.MakeSound(); // Output: "Animal makes a sound."


cat1.MakeSound(); // Output: "Animal makes a sound."
cat2.MakeSound(); // Output: "Cat makes a sound."

Relationships Between Classes

its about lifetime of classes and how class work together in big projects.

Association (Use a)

One to One Relationship

Mean that class A use class B, but class A lifetime not depend on class B lifetime.

class Department
{
public string? Name { get; set; }
}

class Employee
{
public string? Name { get; set; }

// Employee Use Department Class


//But Deleting Emplpyee Class will not effect Depar
public Department? Department { get; set; }

C# Programming Language 44
Aggregation (Has a)

One to One Relationship & One to Many Relationship

When class A has class B as fields, but not using it, if class A Deleted, it will not
effect class B, it will just belong to the new class A.

class Department
{
public string? Name { get; set; }
}

class Company
{
public string? Name { get; set; }

// Company Has Lot of Department


// But if Company Deleting, Department will not
// it will be belong to other company
public Department? Department { get; set; }
}

Composition (Owns a)

One to One Relationship & One to Many Relationship

when class A has and use class B as fields, if class A Deleted, class B will get
deleted also, because class A own class B.

class Vicale
{
public string? Name { get; set; }

// Vicale own an Engine, so when vicale is Distoryed


// the Engine will be distoryed eaither.
public Engine? Engine { get; set; }
}

class Engine
{
public string? Model { get; set; }

C# Programming Language 45
public int CC { get; set; }
}

Advanced OOP Keywords


Interfaces
Another way to achieve abstraction in C#, is with interfaces.

An interface is a completely "abstract class", which can only contain abstract methods and
properties (with empty bodies).

It is considered good practice to start with the letter "I" at the beginning
of an interface, as it makes it easier for yourself and others to remember
that it is an interface and not a class.

Abstract Class Interface

abstract class Shop public interface IShop


{ {
public abstract void Ope public void Open();
public void Close();
// Concrete }
public void Close()
{
Console.WriteLine("S
}
}

Interface Rules

you can’t set bodies to function in interface.

you have to implement all method you create in interface in base class (Parent).

you can inherit more than one interface to one class.

Interface members are by default abstract and public.

An interface cannot contain a constructor (as it cannot be used to create objects).

C# Programming Language 46
Interface can inherit from another interface (one or more).

public interface IShape public class Rectangle : IS


{ {
double CalculateArea public double Length {
} public double Width { g
public double CalculateA
public interface IColor {
{ return Length * Wid
string GetColor(); }

double CalculateArea public string GetColor(


} {
return "Red";
}
}

Explicit interface implementation

when you have multi interface that have same properties with same name, how you
detected which interface you need to use it’s methods or fields and here come explicitly
implementation.

public class Circle : IColo public interface IColorF


{ {
public double Radius { g
}
double IShape.CalculateA
{
using AdvancedOOP.Classes;
return Radius * Radi
}
Rectangle rectangle = new Re
rectangle.Length = 20.2;
double IColor.CalculateA
rectangle.Width = 18.23;
{
rectangle.CalculateArea();
return 0;
Circle circle = new Circle()
}
circle.Radius = 3.21;
IShape shape = circle;
string IColor.GetColor(

C# Programming Language 47
{ Console.WriteLine(shape.Calc
return "Blue"; IColor color = circle;
} Console.WriteLine(color.Calc
}

Classes Other Type


Structures

its value type whereas a class is reference type, more complex of simple type, and look
exactly like class.

Create much more easily and quickly than heap type.

using structure it become easy to copy variables values into stack.

public struct Point


{
public int x { get; set; }
public int y { get; set; }
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
public void MovePoint()
{
x = x++;
}
}

Point p = new Point(2, 3);


Console.WriteLine(p.x);
p.MovePoint(); // x can't increment becuse structures is Va
Console.WriteLine(p.x);

Enumeration

C# Programming Language 48
An enum is a special "class" that represents a group of constants (unchangeable/read-
only variables).

enum DaysOfWeek
{
Monday = 2,
Tuesday = 3,
Wensday = 4,
Thrusday = 5,
Friday = 6,
Satrday = 0,
SunDay = 1
}

enum TraffecLight
{
Green = 1,
Yellow = 2,
Red = 3
}

// Convert enum to int


var m = (int)DaysOfWeek.Friday;
Console.WriteLine(m);

// Convert int to enum


int x = 5;
var z = (DaysOfWeek)x;
Console.WriteLine(z);

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


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

var enumInput = (TraffecLight)input;

switch (enumInput)
{
case TraffecLight.Red:

C# Programming Language 49
{
Console.WriteLine("Start");
break;
}
case TraffecLight.Yellow:
{
Console.WriteLine("Prepare");
break;
}
case TraffecLight.Green:
{
Console.WriteLine("Go");
break;
}
default:
{
Console.WriteLine("Chose number between 1 - 3 i
break;
}
}

Important Keywords
Static Keyword

is a modifier in C# which is applicable for the following:

Classes

Variables

Methods

Constructor

its Utility for use in code not to store data, and can’t make instant of static class.

// Can't make instant of static class.


// Static Class ===> Utilitys for use in code not to store
public static class Family
{
public static string? FatherName;

C# Programming Language 50
public static string? MotherName;

public static bool HasFamily()


{
if (!string.IsNullOrEmpty(FatherName) && !string.
{
return true;
}
else
{
return false;
}

}
}

// Static Faild into Non-Static Class

public class Vichel


{
// Shared State
public static int NumberOfCalls = 0;

public Vichel() // Constructor


{
System.Console.WriteLine("Normal Constructor Calle
NumberOfCalls++;
}

// Call with first Instant only (one time only).


// Access static members (faild , method) make static
static Vichel()
{
Console.WriteLine("Static Constructor Called");
}

public static void Drive()


{

C# Programming Language 51
Console.WriteLine(NumberOfCalls);
}
}

Family.FatherName = "Ziad";
Family.MotherName = "Ola";
Console.WriteLine(Family.HasFamily());

Vichel car = new Vichel();


Vichel car2 = new Vichel();
Vichel.NumberOfCalls = 5;
Vichel.Drive();

NameSpace

Used to organize the classes. it helps to control the scope of methods and classes in larger
projects.

namespace name_of_nameSpace
{

// Nested NameSpace
namespace name_of_nestedNameSpace
{

//Classes
class class_name
{

//Interfaces
interface interface_name
{

C# Programming Language 52
//Structures
struct struct_name
{

//Delegates
delegate void delegate_name(); // Talk Bout it later

Project Structure
Files I/O Library
we have two class we can use to deal with files and each include into Files I/O Library.

Stream (Reader & Writer) class

stream is a wrapper or an abstract class that provides the required methods to read, write,
and perform other relevant operations with bytes.

Stream Reader: is designed for character input in a particular encoding.

Stream Writer: is designed for output in a particular encoding.

// Read file with Stream Reader

StreamReader stream = new StreamReader(@"/Users/medhat/Des


string? Line = stream.ReadLine();
string? Line2 = stream.ReadLine();

string? line;
while ((line = stream.ReadLine()) != null)
{
foreach (char c in line)
{
Console.Write(c);
Thread.Sleep(250);

C# Programming Language 53
}
Console.Write(" ");

// Write file with Stream Writer

string FilePath = @"/Users/medhat/Desktop/files/newFile.tx

StreamWriter streamWriter = new StreamWriter(FilePath);


streamWriter.WriteLine("File Input Video");
streamWriter.Close();

File Class

provide some static method to perform most file operation, such as creating file, copying
and moving a files, deleting files, and work with “File Stream” to read and write stream.

// Read file with File static class

string[] starr = File.ReadAllLines(@"/Users/medhat/Desktop/

foreach (var i in starr)


{
System.Console.WriteLine(i);
}

// Write file with File static class

string FilePath = @"/Users/medhat/Desktop/files/newFile.tx

string message =
@"Hello Every One
This text from C# program
this simulation of log file in any C# project using File s

string newContent = "\nThis is New Line";

C# Programming Language 54
if (File.Exists(FilePath))
{
Console.WriteLine("File Already Exist");
}
else
{
//Create New text
File.WriteAllText(FilePath, message);

//Add to exist text


File.AppendAllText(FilePath, newContent);
}

Advanced
Collections
Generics
Generics Definition

Story: you have a client that want you display product (Name, Price) in application
with integer price and string name, you accept and make this code

class Product{
string Name? {get; set;}
int Price {get; set;}

public void ShowProduct(){


Console.WriteLine($"{Name}-{Price}");
}
}

public void Main(string[] args){

Product product = new Product()


{
Name = "P1",

C# Programming Language 55
Price = 20
}
product.ShowProduct();

That good but then the client came back and ask to show the price in decimal format
but keep the old formate as the same, you accept and do this

class Product{
string Name? {get; set;}
int Price {get; set;}

public void ShowProduct(){


Console.WriteLine($"{Name}-{Price}");
}
}

class ProductWithDecimal{
string Name? {get; set;}
decimal Price {get; set;}

public void ShowProduct(){


Console.WriteLine($"{Name}-{Price}");
}
}

public void Main(string[] args){

Product product = new Product()


{
Name = "P1",
Price = 20
}
product.ShowProduct();

Product decimalProduct = new Product()


{

C# Programming Language 56
Name = "P1",
Price = 20.50
}

decimalProduct.ShowProduct();
}

Thats perfect, then the client came back to make some change about name datatype
to be integer ID, you said to him that will be infinity of classes of possible changes
so the code will be non-readable and performance of app will be bad, and you lose
your client 🥲
Generic is declaring datatype of (class, method, fields, ..) at initialize it,
so you can use different datatype with the same (class, method, fields,
..).

Generics Class

Now Lets use generics type with previous example

class Product<T, U>


{
public T? Name { get; set; }
public U? Price { get; set; }

public void ShowProduct()


{
Console.WriteLine($"{Name}-{Price}");
}
}

Product<string, int> product = new Product<string, int>


{
Name = "P1",
Price = 20
};

product.ShowProduct();

C# Programming Language 57
Product<string, decimal> productTwo = new Product<string
{
Name = "P1",
Price = 20.50m
};

productTwo.ShowProduct();

Product<int, double> productThree = new Product<int, do


{
Name = 2,
Price = 20.19
};

productThree.ShowProduct();

now you make all client possible change with just one class, with readable code, and
better performance.

Generics Method

class Print<U> Print<int> print = new Print


{ print.PrintText/*<string>*/(
public U PrintText<T>(T
{
Console.WriteLine(tex
return num;
}
}

Generics interface

public interface IContainer<T>


{
void Add(T name);
}

C# Programming Language 58
public class Box<T> : IContainer<T>
{
public void Add(T name)
{
// Block of Code
}
}

Generics Constrains

you can set some constrains to your generics type to make sure other developer not use
some type that make logic error on your code.

public interface IContainerConstrains<T> where T : class /


{
void Add(T name);

public class Circle<T> : IContainerConstrains<T> where T :


{
public void Add(T name)
{
Console.WriteLine(name);
}
}

class mean Reference Type only

struct mean Value Type only

Circle<string> circle = new Circle<string>();

circle.Add("Medhat");

//! Error Becuse T is Reference Type Only

// Circle<int> circle = new Circle<int>();

C# Programming Language 59
// circle.Add(10);

you can add more than one constraint in the same generics type.

Collections in C#
Generics Collection
Collection you can use when you want all collection value to be same datatype, and that
make some advantage in your code like:

High Performance.

Type-Safe coding.

Readability.

Example: Lists (Explained Before in Basic fundamental)

Non-Generics Collection

Collection you can use when you don’t care about datatype you just want to store data in
some collection, but this collection make some disadvantage to your code like:

Low Performance.

Non Type-Safe coding.

Bad Readability.

Hard to get an error (Lot of logic error).

Example: ArrayLists

Array List
is non-generics collection type and its dynamic size so you not need to know size of your
list at initializing, but its has no datatype define.

Example:

// Array List (non type-safe)


ArrayList arrayList = new ArrayList(); // Dynamic Object

C# Programming Language 60
arrayList.Add("String in Array List"); // Boxing
arrayList.Add(5);
arrayList.Add(10);
arrayList.Add(15);

Console.Write(arrayList[0]); // Unboxing
arrayList.Remove(10);
arrayList.RemoveAt(2);

arrayList.AddRange(arr);

arrayList.Insert(1, "This is Insert Method");

foreach (var item in arrayList)


{
Console.WriteLine(item);
}

Boxing: Mean convert Value type to Reference type.

UnBoxing: Mean convert Reference type to Value type.

because of (Boxing and UnBoxing) Process in arrayList , it doesn’t


need you to define datatype to it anymore because it will convert
your value to object in initializing process, and convert object to
value again at calling process.

But like we said before it has disadvantage to use because its Non-Generics Collection.

Stack & Queue

Stack is Generics & Non-Generics Collection you can use both of them but
Generics s better, and its Dynamic size

Using Last In First Out process (LIFO)

C# Programming Language 61
Mean last value add to stack it will be first one to get out from the stack using
Push() and Pop() Methods to make this action.

Stack<int> stack = new Stack<int>(/* Array */); // La

stack.Push(5);
stack.Push(3);
stack.Push(9);
// stack.Push("Text");

Console.WriteLine(stack.Pop()); // 9
Console.WriteLine(stack.Pop()); // 3

foreach (var item in stack)


{
Console.WriteLine(item); // 5 becuse size decreme
}

Queue is Generics & Non-Generics Collection you can use both of them but
Generics s better, and its Dynamic size

Using First In First Out process (FIFO)

C# Programming Language 62
Mean First value add to queue it will be first one to get out from the queue using
Enqueue() and Dequeue() Methods to make this action.

Queue<int> queue = new Queue<int>(/* Array */); // Fi

queue.Enqueue(1);
queue.Enqueue(2);
queue.Enqueue(3);
queue.Enqueue(4);

Console.WriteLine(queue.Dequeue()); // 1
Console.WriteLine(queue.Dequeue()); // 2
Console.WriteLine(queue.Dequeue()); // 3

foreach (var item in queue)


{
Console.WriteLine(item); // 4 becuse size decreme
}

Tuple

C# Programming Language 63
its not collection but it more like build in class that you can stored data into it with
different data type and its Generics type, Reference value but it have some properties
you should follow it (Max data you can store in it is 8 fields.)

use tuple to return more than one value from function instead of (out
, ref) parameters.

Tuple<int, string, bool> tuple = new Tuple<int, string, boo

Console.WriteLine(tuple.Item1); // 24
Console.WriteLine(tuple.Item2); // Medhat
Console.WriteLine(tuple.Item3); // false

var Employee1 = Tuple.Create(24, "Employee1", true, 6000.00

Console.WriteLine(Employee1.Rest.Item1.Item2); // Ali

// Using Tuple As Function

Tuple<string, int> GetNameAndAge()


{
return Tuple.Create("Medhat", 25);
}

Console.WriteLine(GetNameAndAge().Item1);
Console.WriteLine(GetNameAndAge().Item2);

Value Tuple (Update of Tuple)


is like tuple but more easy to create and use, very light wight because it value type
not reference type like Tuple .

ValueTuple<int, string, bool> person = (23, "Nor", true


Console.WriteLine(person.Item1); // 23
Console.WriteLine(person.Item2); // Nor
Console.WriteLine(person.Item3); // true

// Other Way to create value tuple

C# Programming Language 64
(string,string,int) car = ("Nissan" , "Hatshback" , 2009
Console.WriteLine(car.Item1); // Nissan
Console.WriteLine(car.Item2); // Hatshback
Console.WriteLine(car.Item3); // 2009

You can also name your fields in value type

(string Model,string Type,int Year) car = ("Nissan" , "H


Console.WriteLine(car.Model); // Nissan
Console.WriteLine(car.Type); // Hatshback
Console.WriteLine(car.Year); // 2009

Also it easier with creating and calling function

(string Model, int Year) GetModelAndYear()


{
return ("Nissan", 2009);
}

(string CarModel, int CarYear) = GetModelAndYear();

Console.WriteLine(CarModel);
Console.WriteLine(CarYear);

Key Value Per Collections


Stored data with unique key for each value like Dictionary (Explained before in Basics
Fundamental).

Using Example:

Setting.

Cashing.

Database (Light Wight).

Sorted List
Generics Collection Type, its like dictionary at everything but its Sorted.

C# Programming Language 65
SortedList<int, string> sortedList = new SortedList<int, s
{2,"Medhat"} ,
{1, "Ahmed"}
};

foreach (KeyValuePair<int, string> item in sortedList)


{
Console.WriteLine(item.Key);
Console.WriteLine(item.Value);
}

Hash Table

Non-Generics Collections, And absolute that return DictionaryEntry data type.

Hashtable hashtable = new Hashtable(){


{10,"Product 1"} ,
{"Boolean", false}
};

foreach (DictionaryEntry item in hashtable)


{
Console.Write(item.Key + ": ");
Console.Write(item.Value + "\n");
}

Collection Internal
IEnumerable

All collections we talk about before Implement IEnumerable interface, IEnumerable


allow foreach keyword to work with all this collections

IEnumerable hold all value of a list (array , stack , tuple , …) and in


its contract have just one method called GetEnumerator() and this
method return IEnumerator.

let’s create new collection called ShopList that implement IEnumerable interface

C# Programming Language 66
public class ShopingList : IEnumerable
{
public IEnumerator GetEnumerator()
{
throw new NotImplementedException();
}
}

now as you can see ShopingList class have GetEnumerator method from IEnumerable
interface and this method return an collection (List , Array , Stack ….).

IEnumerator

IEnumerator is a (Person) who deal with all data in our list, it get the
data from GetEnumerator method.

now let’s create ShopListEnumerator for our ShopList.

public class ShopingListEnumerator : IEnumerator


{
public object Current => throw new NotImplementedExcep

public bool MoveNext()


{
throw new NotImplementedException();
}

public void Reset()


{
throw new NotImplementedException();
}
}

now as we can see IEnumerator implement three method

Current: Hold the start position of our list.

MoveNext: return true if the position move forward to next value successfully, and
return false when it can’t get the next value of our list.

C# Programming Language 67
Reset: reset the position to start point when foreach finished the process.

Let’s add some logic to our ShopingListEnumerator

public class ShopingListEnumerator : IEnumerator


{
private string[] _items { get; set; }
private int position = -1;
public ShopingListEnumerator(string[] items)
{
_items = items;
}
public object Current
{
get
{
return _items[position];
}
}

public bool MoveNext()


{
position++;

if (position < _items.Length)


{

return true;
}
else
{
return false;
}
}

public void Reset()


{
position = -1;

C# Programming Language 68
}
}

As we can see we create constructor to get our list from ShopingList class, create
position variable to control the position of list, and set condition in MoveNext method to
make sure our position will move correctly.

return to ShopingList class, Let’s return our IEnumerator in GetEnumerator method.

public class ShopingList : IEnumerable


{
string[] items = new string[3] { "Bread", "Milk", "Bea

public IEnumerator GetEnumerator()


{
return new ShopingListEnumerator(items);
}
}

now we ready to test foreach method in our application with this new collection call
ShopingList.

ShopingList shopingList = new ShopingList();

foreach (var item in shopingList)


{
Console.WriteLine(item);
}

And This how all collection work in C# with deferent Logic but same
way as they implement IEnumerable interface and using IEnumerator to
deal with value.

Indexer

C# Programming Language 69
in any collection you can get and set value in collection using index like this

List<int> list = new List<int>();

list.Add(5); // Index 0
list.Add(3); // Index 1
list.Add(8); // Index 2

Console.WriteLine(list[1]); // 3

Now let’s go Under the hood to know how indexer work and create customs indexer

let’s create Book Class and BookCollection Class.

public class Book public class BookCollection


{ {
public string? Title { ge private Book[] books = n
public string? Author { g }
}

Main Goal is create object from BookCollection and use index to set
& get Book Class info to our array in BookCollection Class

Indexer is a normal properties with get and set but return the type of class you stored in
collection array.

Customs indexer useful when you need to add your logic to the collection because each
collection you use has its own logic.

public class BookCollection


{
private Book[] books = new Book[5];

public Book this[int Index]


{
get

C# Programming Language 70
{
return books[Index];
}
set
{
books[Index] = value;
}
}

BookCollection bookCollection = new BookCollection();

bookCollection[0] = new Book() { Title = "GOT", Author = "R


bookCollection[1] = new Book() { Title = "Lord of the ring

Console.WriteLine(bookCollection[0].Title);
Console.WriteLine(bookCollection[0].Author);

In customs indexer you can make indexer overloading to make your collection able to get
or set with different datatype & value.

public class BookCollection


{
private Book[] books = new Book[5];

public Book this[int Index]


{
get
{
return books[Index];
}
set
{
books[Index] = value;
}
}

C# Programming Language 71
public Book this[string Title]
{
get
{
foreach (var book in books)
{
if (book.Title == Title)
{
return book;
}
}
return null;
}
set
{
for (int i = 0; i < books.Length; i++)
{
if (books[i].Title == Title)
{
books[i] = value;
return;
}
}

// Throw Exception if Not Found (Or Create new


}
}

BookCollection bookCollection = new BookCollection();

bookCollection[0] = new Book() { Title = "GOT", Author = "R


bookCollection[1] = new Book() { Title = "Lord of the ring

C# Programming Language 72
Console.WriteLine(bookCollection["GOT"].Title);
Console.WriteLine(bookCollection["Lord of the ring"].Autho

Advanced C# v.2 - v.3


Delegates And Lamda
Delegates

A delegate is an object which refers to a method or you can say it is a reference type
variable that can hold a reference to the methods.it provides a way which tells which
method is to be called when an event is triggered.

Method Signuture Delegates Using (Return Type , Parameters)


Method Signature to valid the method when
Access Modifier
use it with delegates.
Return Type
Important Points About Delegates:
Method Name
Flexibility with coding
Parameters
achieve Parameterizing principal.
Method Body
Delegates must have instance object like
class, etc..

Example:

Make a function that get numbers that grater than 10

static List<int> GetValueGraterThan10(List<int> listOne)


{
List<int> result = new List<int>();
foreach (var item in listOne)
{
if (item > 10)
{
result.Add(item);
}
}

C# Programming Language 73
return result;
}

Now Make it to return numbers grater than 15

static List<int> GetValueGraterThan15(List<int> listOne)


{
List<int> result = new List<int>();
foreach (var item in listOne)
{
if (item > 15)
{
result.Add(item);
}
}

return result;
}

we can’t have two function doing the same operation try to Using (DRY) principle.

static List<int> GetValueGraterThan(List<int> listOne, int x)


{
List<int> result = new List<int>();
foreach (var item in listOne)
{
if (item > x)
{
result.Add(item);
}
}

return result;
}

Ok that good. but what if we need to Get number Less than to grater than what can we do?
(Without Create another functions).

Here come Delegates to solve this problem as code below

C# Programming Language 74
delegate bool CheckDelegates(int numOne, int numTwo); // Decla

static bool GraterThan(int x, int y) // Operation Method


{
return x > y;
}

static bool LessThan(int x, int y) // Operation Method


{
return x < y;
}

static List<int> GetFilterToValue(List<int> listOne, int x, C


{
List<int> result = new List<int>();
foreach (var item in listOne)
{
if (operations(item, x))
{
result.Add(item);
}
}

return result;
}

At Main Method:

List<int> list = new List<int>() { 10, 15, 20, 5, 3, 22 };

var result1 = GetFilterToValue(list, 15, GraterThan);


var result2 = GetFilterToValue(list, 1, LessThan);

foreach (var item in result1)


{

C# Programming Language 75
Console.WriteLine(item);
}

And now we have just one function with multi operation and without limit numbers of choice.

later we will learn to create delegate without creating methods that


we will use in it by using (Anonymous Method And Lamda).

Anonymous Methods And Lamda Expressions

we will explain this chapter using delegates so make sure that you understand how
delegates work.

C# v.2 : Anonymous Methods Created and can be use to make delegates method be
inline (one line of code) Example:
Before Anonymous Methods

delegate bool CheckDelegates(int numOne, int numTwo); //

static bool GraterThan(int x, int y) // Operation Method


{
return x > y;
}

static bool LessThan(int x, int y) // Operation Method


{
return x < y;
}

After Anonymous Methods

CheckDelegates GraterThan = delegate (int x, int y)


{
return x > y;
}; // Anonymous Method (instations)

CheckDelegates LessThan = delegate (int x, int y)


{

C# Programming Language 76
return x < y;
}; // Anonymous Method (instations)

The Different is without creating all function that u use as


delegate , you can create anonymous methods (without name)
and use it as delegate at same line.
C# v.3 : Lamda Expressions Crated to make anonymous function to be used in other
parameter without creating it in another line Like Below:

var result4 = GetFilterToValue(list, 15, (int x, int y)


foreach (var i in result4)
{
Console.WriteLine(i);
}

Now as you see we create a call of method that need delegate as parameters , but
without take instance of delegate or create new one, with lamda expressions we can
create and initializing delegate in one line.

Delegate Chains

we have three methods with string return type and one string parameter, and one
delegate.

using += to add method to object of delegate.


using -= to remove method to object of delegate.

delegate string DelegateChain(string input);


public static void Main(string[] args)
{
DelegateChain delegateChain = (string input) => $"M
delegateChain += (string input) => $"Method Two: {i
delegateChain += (string input) => $"Method Three:
NewClass newClass = new NewClass();
delegateChain += newClass.MethodFour;

C# Programming Language 77
Console.WriteLine(delegateChain("My String"));// Me
}

GetInvocationList()
return Array of Delegate which inside of delegate object, and each method have two
properties (Method, Target)

var delgatesArr = delegateChain.GetInvocationList();

foreach (var item in delgatesArr)


{
Console.WriteLine($"Method: {item.Method}");
Console.WriteLine($"Target: {item.Target}");
}

Method: return method name and its paramete.

Target: return the class which have the method inside it, and return null if
method was static because static can’t have instance object.

Generics Delegates

We have two method one of then int return type and other is string return type, create a
delegate for this 2 method.
before you go and create delegate for each method , let’s use generics delegate.

delegate T SumIntOrString<T>(T x, T y); // Generics Delega

public static void Main(string[] args)


{
SumIntOrString<int> sumIntOrString1 = (int x , int
SumIntOrString<string> sumIntOrString2 = (string x , s

Console.WriteLine(sumIntOrString1(1, 2)); // 3
Console.WriteLine(sumIntOrString2("Medhat", " Assem"))
}

Fun, Actions And Predicate

C# Programming Language 78
Func : its a delegate take up to 16 parameters and its build-in in .Net Framework,
and its generics type, it can’t return void type,

Func < Parameters ,.., Return Type > FuncName = Method;

Func<int, int, int> func = (int x, int y) => x + y;

Console.WriteLine(func(5, 2)); // 7

Actions

its like a Func but its used to return void type only.
Action < Parameters ,..> ActionName = Method;

Action<string, string> action = (string textOne, string


=> Console.WriteLine($"{textOne} {textTwo}");

action("Medhat", "Assem");

Predicate
its like Func And Action but its Used to return boolean type, and it take only one
parameters.
Predicate < Parameters > PredicateName = Method;

Predicate<int> predicate = (int x) =>


{
if (x % 2 == 0)
{
return true;
}
else
{
return false;
}
};

Console.WriteLine(predicate(4));

C# Programming Language 79
Events
Events & Observer Pattern

Let’s understand the event by example:

We need to create application that user can upload new video to his youtube channel
and subscriber get notification that user upload new video and they can watch it.

First Create Youtube Channel Class

public class YouTubeChannel


{
public void UploadVideo(string videoName)
{
Console.WriteLine($"{videoName} Uploaded");

}
}

Then Create Subscriber Class

public class Subscriber


{
public void Subscrib(YouTubeChannel channel)
{

}
public void WatchTheVideo(string videoName)
{
Console.WriteLine($"Watching {videoName}");
}

Now let’s create a delegate to point the UploadVideo method in subscriber class

public delegate void VideoUpload(string videoName);


public class YouTubeChannel
{
public VideoUpload? videoUpload;

C# Programming Language 80
public void UploadVideo(string videoName)
{
Console.WriteLine($"{videoName} Uploaded");
videoUpload(videoName);
}
}

public class Subscriber


{
public void Subscrib(YouTubeChannel channel)
{
channel.videoUpload += WatchTheVideo;
}
public void WatchTheVideo(string videoName)
{
Console.WriteLine($"Watching {videoName}");
}

Let’s Use this code in out man

YouTubeChannel channel = new YouTubeChannel();

Subscriber subscriberOne = new Subscriber();


Subscriber subscriberTwo = new Subscriber();
Subscriber subscriberThree = new Subscriber(

subscriberOne.Subscrib(channel);
subscriberTwo.Subscrib(channel);
subscriberThree.Subscrib(channel);

channel.UploadVideo("Video One");
channel.UploadVideo("Video Two");
channel.UploadVideo("Video Three");

Now We got two problem

C# Programming Language 81
1. Direct Invoke : subscriber get notification without uploading any video

channel.videoUpload("x");

2. Set Delegate Object To Null : That will delete all your subscriber when
upload video

channel.videoUpload = null;

Event Keyword Solve This Problem by prevent the to line of code to work (Give
syntax Error)

public event VideoUpload? videoUpload; // That Prevent T

Observer Pattern: its like someone watch your channel


“YouTubeChannel” for any new video that you upload and sent
notification to your subscriber “Subscriber”.

Event Handler & Event Args

its a build in Delegate that have 2 parameters, and its has 2 type to use:

Non-Generics Handler : handle events with no return data

public delegate void VideoUpload(string videoName);


public class YouTubeChannel
{
public event EventHandler? videoUpload;
public void UploadVideo(string videoName)
{
Console.WriteLine($"{videoName} Uploaded");
videoUpload(this , EventArgs.Empty); // (sernde

}
}

C# Programming Language 82
public class Subscriber
{
public void Subscrib(YouTubeChannel channel)
{
channel.videoUpload += WatchTheVideo;
}
public void WatchTheVideo(object sender, EventArgs e
{
Console.WriteLine($"Watching Video");
}

Generics Handler : handle events with return data

public event EventHandler<string>? videoUpload;

public void WatchTheVideo(object sender, string e)


{
Console.WriteLine($"Watching {e} Video");
}

Covariance And Contra-Variance


Covariance

able to pass drive class when base class is Expected

Apple apple1 = new Apple();


Fruit apple = new Apple();

Orange orange1 = new Orange();


Fruit orange = new Orange();

With Delegates

C# Programming Language 83
public delegate Apple CreateAppleDelegate();

public delegate Orange CreateOrangeDelegate();

public delegate Fruit CreateFruitDelegate();

// First Way
CreateAppleDelegate createApple = apple1.CreateNewApple;
createApple();

CreateOrangeDelegate createOrange = orange1.CreateNewOrange


createOrange();

// Second Way
CreateFruitDelegate createFruitDelegateApple = apple1.Crea
CreateFruitDelegate createFruitDelegateOrange = orange1.Cre

// Third Way
CreateFruitDelegate createFruitDelegate = apple1.CreateNewA
createFruitDelegate += orange1.CreateNewOrange;

createFruitDelegate();

Contra-Variance

Can’t pass base class even when drive class is Expected.

Asynchronous Programming
Threading

Others

C# Programming Language 84
Partial Class
A partial class is a special feature of C#. It provides a special ability to implement the
functionality of a single class into multiple files and all these files are combined into a single
class file when the application is compiled.

using System; using System;

namespace Others.Classes; namespace Others.Classes;

public partial class Person public partial class Person


{ {
public string? Name { ge public string GetFullInf
public int Age { get; se {
return $"{Name}-{Age
public Person(string Name }
{ }
this.Name = Name;
this.Age = Age;
}
}

class Program
{
static void Main(string[] args)
{
#region Partial Class

Person person = new Person("Medhat", 25);


Console.WriteLine(person.GetFullInfo());

#endregion
}
}

Advantages :

C# Programming Language 85
With the help of partial classes, multiple developers can work simultaneously in the same
class in different files.

With the help of a partial class concept, you can split the UI of the design code and the
business logic code to read and understand the code.

When you were working with automatically generated code, the code can be added to the
class without having to recreate the source file like in Visual studio.

You can also maintain your application in an efficient manner by compressing large
classes into small ones.

Partial Method
C# contains a special method is known as a partial method, which contains declaration part in
one partial class and definition part in another partial class or may contain both declaration
and definition in the same partial class.

partial void GetOnlyName(string Name);

partial void GetOnlyName(string Name)


{
Name = this.Name;
Console.WriteLine(Name);
}

Finalizer (OOP)
its a method inside a class used to destroy instances of that class.

Destructor : called when object of constructor disposed.

public class Finalizer


{
public string? Name { get; set; }
public Finalizer()
{
Console.WriteLine("This is Finalizer Constructor")
}

C# Programming Language 86
~Finalizer()
{
Console.WriteLine("This is Finalizer Destructor");
}
}

When object get disposed? Garbage Collection

End of program execution (Implicit) Automatic Memory Management

Memory Full (Implicit)

Using GC.Collect (Explicit)

Using GC Class to collect garbage (Explicitly)

var F = new Finalizer(); // static void MakeSomeGarabage


{
MakeSomeGarabage(); // false Version V;

Console.WriteLine($"Memory U for (int i = 0; i < 1000


GC.Collect(); // Start clean {
Console.WriteLine($"Memory U V = new Version(); /
}
}

Nested Type
its define class inside another class.

public class NewClass


{
public class NestedClass
{

}
}

C# Programming Language 87
NewClass.NestedClass nestedClass = new NewClass.NestedClass()

C# Programming Language 88

You might also like