0% found this document useful (0 votes)
28 views67 pages

Short Syllbus Visual C Sharp Programming Notes 5th Semester

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
0% found this document useful (0 votes)
28 views67 pages

Short Syllbus Visual C Sharp Programming Notes 5th Semester

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

C# ( Sharp ) Complete Notes

What is C#?
C# is pronounced "C-Sharp".
It is an object-oriented programming language created by Microsoft that runs on the .NET Framework.
C# has roots from the C family, and the language is close to other popular languages
like C++ and Java.
The first version was released in year 2002. The latest version, C# 12, was released in November
2023.
C# is used for:
 Mobile applications
 Desktop applications
 Web applications
 Web services

Why Use C#?


 It is one of the most popular programming languages in the world
 It is easy to learn and simple to use
 It has huge community support

C# Syntax
In the previous chapter, we created a C# file called Program.cs, and we used the following code to
print "Hello World" to the screen:
using System;
namespace HelloWorld
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}

Example explained
Line 1: using System means that we can use classes from the System namespace.
Line 2: A blank line. C# ignores white space. However, multiple lines makes the code more readable.
Line 3: namespace is used to organize your code, and it is a container for classes and other
namespaces.
Line 4: The curly braces {} marks the beginning and the end of a block of code.
Line 5: class is a container for data and methods, which brings functionality to your program. Every
line of code that runs in C# must be inside a class. In our example, we named the class Program.
Line 7: Another thing that always appear in a C# program is the Main method. Any code inside its
curly brackets {} will be executed. You don't have to understand the keywords before and after Main.
You will get to know them bit by bit while reading this tutorial.
Line 9: Console is a class of the System namespace, which has a WriteLine() method that is used to
output/print text. In our example, it will output "Hello World!".
If you omit the using System line, you would have to write System.Console.WriteLine() to print/output
text.
Note: Every C# statement ends with a semicolon ;.
Note: C# is case-sensitive; "MyClass" and "myclass" have different meaning.

C# Output
To output values or print text in C#, you can use the WriteLine() method:
Example
Console.WriteLine("Hello World!");

we will only use WriteLine() as it makes it easier to read the output of code.

pg. 1
C# ( Sharp ) Complete Notes

C# Comments
Comments can be used to explain C# code, and to make it more readable. It can also be used to
prevent execution when testing alternative code.
Single-line Comments
Single-line comments start with two forward slashes (//).
Any text between // and the end of the line is ignored by C# (will not be executed).
This example uses a single-line comment before a line of code:
// This is a comment
Console.WriteLine("Hello World!");

C# Multi-line Comments
Multi-line comments start with /* and ends with */.
Any text between /* and */ will be ignored by C#.
This example uses a multi-line comment (a comment block) to explain the code:
Example
/* The code below will print the words Hello World
to the screen, and it is amazing */
Console.WriteLine("Hello World!");

Single or multi-line comments?


It is up to you which you want to use. Normally, we use // for short comments, and /* */ for longer.

C# Variables
Variables are containers for storing data values.
In C#, there are different types of variables (defined with different keywords), for example:
 int - stores integers (whole numbers), without decimals, such as 123 or -123
 double - stores floating point numbers, with decimals, such as 19.99 or -19.99
 char - stores single characters, such as 'a' or 'B'. Char values are surrounded by single quotes
 string - stores text, such as "Hello World". String values are surrounded by double quotes
 bool - stores values with two states: true or false
Syntax
type variableName = value;
Example
Create a variable called name of type string and assign it the value "Rashid":
string name = "Rashid";
Console.WriteLine(name);
Example
Create a variable called myNum of type int and assign it the value 15:
int myNum = 15;
Console.WriteLine(myNum);

Example
int myNum;
myNum = 15;
Console.WriteLine(myNum);

Other Types
A demonstration of how to declare variables of other types:
Example
int myNum = 5;
double myDoubleNum = 5.99D;
char myLetter = 'D';
bool myBool = true;
string myText = "Hello";

Constants
If you don't want others (or yourself) to overwrite existing values, you can add the const keyword in
front of the variable type.

pg. 2
C# ( Sharp ) Complete Notes

This will declare the variable as "constant", which means unchangeable and read-only:
Example
const int myNum = 15;
myNum = 20; // error

Note: You cannot declare a constant variable without assigning the value. If you do, an error will
occur: A const field requires a value to be provided.

Display Variables
The WriteLine() method is often used to display variable values to the console window.
To combine both text and a variable, use the + character:
Example
string name = "Rashid";
Console.WriteLine("Hello " + name);
Example
string firstName = "Muhammad ";
string lastName = "Rashid";
string fullName = firstName + lastName;
Console.WriteLine(fullName);

For numeric values, the + character works as a mathematical operator (notice that we use int (integer)
variables here):
Declare Many Variables
To declare more than one variable of the same type, use a comma-separated list:
int x = 5, y = 6, z = 50;
Console.WriteLine(x + y + z);
You can also assign the same value to multiple variables in one line:
Example
int x, y, z;
x = y = z = 50;
Console.WriteLine(x + y + z);

C# Identifiers
All C# variables must be identified with unique names.
These unique names are called identifiers.
Identifiers can be short names (like x and y) or more descriptive names (age, sum, totalVolume).
Note: It is recommended to use descriptive names in order to create understandable and maintainable
code:
Example
// Good
int minutesPerHour = 60;
// OK, but not so easy to understand what m actually is
int m = 60;
The general rules for naming variables are:
 Names can contain letters, digits and the underscore character (_)
 Names must begin with a letter or underscore
 Names should start with a lowercase letter, and cannot contain whitespace
 Names are case-sensitive ("myVar" and "myvar" are different variables)
 Reserved words (like C# keywords, such as int or double) cannot be used as names
C# Data Types

As explained in the variables chapter, a variable in C# must be a specified data type:

pg. 3
C# ( Sharp ) Complete Notes

Example
int myNum = 5; // Integer (whole number)
double myDoubleNum = 5.99D; // Floating point number
char myLetter = 'D'; // Character
bool myBool = true; // Boolean
string myText = "Hello"; // String
A data type specifies the size and type of variable values.
It is important to use the correct data type for the corresponding variable; to avoid errors, to save time
and memory, but it will also make your code more maintainable and
readable. The most common data types are:

Data Type Size Description

int 4 bytes Stores whole numbers from -2,147,483,648 to 2,147,483,647

long 8 bytes Stores whole numbers from -9,223,372,036,854,775,808 to


9,223,372,036,854,775,807

float 4 bytes Stores fractional numbers. Sufficient for storing 6 to 7 decimal digits

double 8 bytes Stores fractional numbers. Sufficient for storing 15 decimal digits

bool 1 bit Stores true or false values

char 2 bytes Stores a single character/letter, surrounded by single quotes

string 2 bytes per character Stores a sequence of characters, surrounded by double quotes

Numbers
Number types are divided into two groups:
Integer types stores whole numbers, positive or negative (such as 123 or -456), without decimals.
Valid types are int and long. Which type you should use, depends on the numeric value.
Floating point types represents numbers with a fractional part, containing one or more decimals.
Valid types are float and double.
Even though there are many numeric types in C#, the most used for numbers are int (for whole
numbers) and double (for floating point numbers). However, we will describe them all as you continue
to read.

Integer Types
Int
The int data type can store whole numbers from -2147483648 to 2147483647. In general, and in our
tutorial, the int data type is the preferred data type when we create variables with a numeric value.
Example
int myNum = 100000;
Console.WriteLine(myNum);
Long
The long data type can store whole numbers from -9223372036854775808 to 9223372036854775807.
This is used when int is not large enough to store the value. Note that you should end the value with
an "L":
Example
long myNum = 15000000000L;
Console.WriteLine(myNum);

Floating Point Types


You should use a floating point type whenever you need a number with a decimal, such as 9.99 or
3.14515.
The float and double data types can store fractional numbers. Note that you should end the value with
an "F" for floats and "D" for doubles:
pg. 4
C# ( Sharp ) Complete Notes

Float Example
float myNum = 5.75F;
Console.WriteLine(myNum);
Use float or double?
The precision of a floating point value indicates how many digits the value can have after the decimal
point. The precision of float is only six or seven decimal digits, while double variables have a precision
of about 15 digits. Therefore it is safer to use double for most calculations.
Scientific Numbers
A floating point number can also be a scientific number with an "e" to indicate the power of 10:
Example
float f1 = 35e3F;
double d1 = 12E4D;
Console.WriteLine(f1);
Console.WriteLine(d1);
Booleans
A boolean data type is declared with the bool keyword and can only take the values true or false:
Example
bool isCSharpFun = true;
bool isFishTasty = false;
Console.WriteLine(isCSharpFun); // Outputs True
Console.WriteLine(isFishTasty); // Outputs False
Characters
The char data type is used to store a single character. The character must be surrounded by single
quotes, like 'A' or 'c':
Example
char myGrade = 'B';
Console.WriteLine(myGrade);
Strings
The string data type is used to store a sequence of characters (text). String values must be
surrounded by double quotes:
Example
string greeting = "Hello World";
Console.WriteLine(greeting);
C# Type Casting
Type casting is when you assign a value of one data type to another type.
In C#, there are two types of casting:
 Implicit Casting (automatically) - converting a smaller type to a larger type size
char -> int -> long -> float -> double

 Explicit Casting (manually) - converting a larger type to a smaller size type


double -> float -> long -> int -> char
Implicit Casting
Implicit casting is done automatically when passing a smaller size type to a larger size type:
Explicit Casting
Explicit casting must be done manually by placing the type in parentheses in front of the value:

Why Conversion?
Many times, there's no need for type conversion. But sometimes you have to. Take a look at the next
chapter, when working with user input, to see an example of this.
Get User Input
You have already learned that Console.WriteLine() is used to output (print) values. Now we will
use Console.ReadLine() to get user input.
In the following example, the user can input his or hers username, which is stored in the
variable userName. Then we print the value of userName:
Example
// Type your username and press enter
Console.WriteLine("Enter username:");

pg. 5
C# ( Sharp ) Complete Notes

// Create a string variable and get user input from the keyboard and store it in the variable
string userName = Console.ReadLine();

// Print the value of the variable (userName), which will display the input value
Console.WriteLine("Username is: " + userName);
User Input and Numbers
The Console.ReadLine() method returns a string. Therefore, you cannot get information from another
data type, such as int. The following program will cause an error:
Note: If you enter wrong input (e.g. text in a numerical input), you will get an exception/error
message (like System.FormatException: 'Input string was not in a correct format.').

Operators
Operators are used to perform operations on variables and values.
In the example below, we use the + operator to add together two values:
int x = 100 + 50;
Although the + operator is often used to add together two values, like in the example above, it can also
be used to add together a variable and a value, or a variable and another variable:
Example
int sum1 = 100 + 50; // 150 (100 + 50)
int sum2 = sum1 + 250; // 400 (150 + 250)
int sum3 = sum2 + sum2; // 800 (400 + 400)
Operator Name Description Example

+ Addition Adds together two values x+y

- Subtraction Subtracts one value from another x-y

* Multiplication Multiplies two values x*y

/ Division Divides one value by another x/y

% Modulus Returns the division remainder x%y

++ Increment Increases the value of a variable by 1 x++

-- Decrement Decreases the value of a variable by 1 x--

Assignment Operators
Assignment operators are used to assign values to variables.
In the example below, we use the assignment operator (=) to assign the value 10 to a variable
called x:
Example
int x = 10;
The addition assignment operator (+=) adds a value to a variable:
Example
int x = 10;
x += 5;
Comparison Operators
Comparison operators are used to compare two values (or variables). This is important in
programming, because it helps us to find answers and make decisions.
The return value of a comparison is either True or False. These values are known as Boolean values,
and you will learn more about them in the Booleans and If..Else chapter.
In the following example, we use the greater than operator (>) to find out if 5 is greater than 3:
Example
int x = 5;
int y = 3;
Console.WriteLine(x > y); // returns True because 5 is greater than 3

pg. 6
C# ( Sharp ) Complete Notes

Operator Name Example

== Equal to x == y

!= Not equal x != y

> Greater than x>y

< Less than x<y

>= Greater than or equal to x >= y

<= Less than or equal to x <= y

Logical Operators
As with comparison operators, you can also test for True or False values with logical operators.
Logical operators are used to determine the logic between variables or values:
Logical operators are used to determine the logic between variables or values:
Operator Name Description Example

&& Logical and Returns True if both statements are true x < 5 && x < 10

|| Logical or Returns True if one of the statements is true x < 5 || x < 4

! Logical not Reverse the result, returns False if the result is true !(x < 5 && x < 10)

You will learn more about comparison and logical operators in the Booleans and If...Else chapters.

Math.Max(x,y)
The Math.Max(x,y) method can be used to find the highest value of x and y:
Example
Math.Max(5, 10);
C# Booleans
Very often, in programming, you will need a data type that can only have one of two values, like:
 YES / NO
 ON / OFF
 TRUE / FALSE
For this, C# has a bool data type, which can take the values true or false.

Boolean Values
A boolean type is declared with the bool keyword and can only take the values true or false:
However, it is more common to return boolean values from boolean expressions, for conditional testing (see below).

Boolean Expression
A Boolean expression returns a boolean value: True or False, by comparing values/variables.
This is useful to build logic, and find answers.
For example, you can use a comparison operator, such as the greater than (>) operator to find out if
an expression (or a variable) is true:

Real Life Example


Let's think of a "real life example" where we need to find out if a person is old enough to vote.
In the example below, we use the >= comparison operator to find out if the age (25) is greater
than OR equal to the voting age limit, which is set to 18:
Example
int myAge = 25;
int votingAge = 18;
pg. 7
C# ( Sharp ) Complete Notes

Console.WriteLine(myAge >= votingAge);

C# Conditions
C# Conditions and If Statements
C# supports the usual logical conditions from mathematics:
 Less than: a < b
 Less than or equal to: a <= b
 Greater than: a > b
 Greater than or equal to: a >= b
 Equal to a == b
 Not Equal to: a != b
You can use these conditions to perform different actions for different decisions.
C# has the following conditional statements:
 Use if to specify a block of code to be executed, if a specified condition is true
 Use else to specify a block of code to be executed, if the same condition is false
 Use else if to specify a new condition to test, if the first condition is false
 Use switch to specify many alternative blocks of code to be executed

The if Statement
Use the if statement to specify a block of C# code to be executed if a condition is True.
Syntax
if (condition)
{
// block of code to be executed if the condition is True
}
Note that if is in lowercase letters. Uppercase letters (If or IF) will generate an error.
In the example below, we test two values to find out if 20 is greater than 18. If the condition is True,
print some text:
Example
if (20 > 18)
{
Console.WriteLine("20 is greater than 18");
}
We can also test variables:
Example
int x = 20;
int y = 18;
if (x > y)
{
Console.WriteLine("x is greater than y");
}
Example explained
In the example above we use two variables, x and y, to test whether x is greater than y (using
the > operator). As x is 20, and y is 18, and we know that 20 is greater than 18, we print to the screen
that "x is greater than y".
The else Statement
Use the else statement to specify a block of code to be executed if the condition is False.
Syntax
if (condition)
{
// block of code to be executed if the condition is True
}
else
{
// block of code to be executed if the condition is False
}
Example
int time = 20;
pg. 8
C# ( Sharp ) Complete Notes

if (time < 18)


{
Console.WriteLine("Good day.");
}
else
{
Console.WriteLine("Good evening.");
}
// Outputs "Good evening."
Example explained
In the example above, time (20) is greater than 18, so the condition is False. Because of this, we move on to the else condition
and print to the screen "Good evening". If the time was less than 18, the program would print "Good day".

The else if Statement

Use the else if statement to specify a new condition if the first condition is False.

Syntax
if (condition1)
{
// block of code to be executed if condition1 is True
}
else if (condition2)
{
// block of code to be executed if the condition1 is false and condition2 is True
}
else
{
// block of code to be executed if the condition1 is false and condition2 is False
}

Example
int time = 22;
if (time < 10)
{
Console.WriteLine("Good morning.");
}
else if (time < 20)
{
Console.WriteLine("Good day.");
}
else
{
Console.WriteLine("Good evening.");
}
// Outputs "Good evening."

Example explained

In the example above, time (22) is greater than 10, so the first condition is False. The next
condition, in the else if statement, is also False, so we move on to the else condition
since condition1 and condition2 is both False - and print to the screen "Good evening".

However, if the time was 14, our program would print "Good day.

Short Hand If...Else (Ternary Operator)

pg. 9
C# ( Sharp ) Complete Notes

There is also a short-hand if else, which is known as the ternary operator because it consists of three
operands. It can be used to replace multiple lines of code with a single line. It is often used to replace
simple if else statements:
Syntax
variable = (condition) ? expressionTrue : expressionFalse;
Instead of writing:
Example
int time = 20;
if (time < 18)
{
Console.WriteLine("Good day.");
}
else
{
Console.WriteLine("Good evening.");
}
You can simply write:
Example
int time = 20;
string result = (time < 18) ? "Good day." : "Good evening.";
Console.WriteLine(result);

C# Switch Statements
Use the switch statement to select one of many code blocks to be executed.
Syntax
switch(expression)
{
case x:
// code block
break;
case y:
// code block
break;
default:
// code block
break;
}

This is how it works:


 The switch expression is evaluated once
 The value of the expression is compared with the values of each case
 If there is a match, the associated block of code is executed
 The break and default keywords will be described later in this chapter
The example below uses the weekday number to calculate the weekday name:

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;

pg. 10
C# ( Sharp ) Complete Notes

case 5:
Console.WriteLine("Friday");
break;
case 6:
Console.WriteLine("Saturday");
break;
case 7:
Console.WriteLine("Sunday");
break;
}
// Outputs "Thursday" (day 4)

The break Keyword


When C# reaches a break keyword, it breaks out of the switch block.
This will stop the execution of more code and case testing inside the block.
When a match is found, and the job is done, it's time for a break. There is no need for more testing.
A break can save a lot of execution time because it "ignores" the execution of all the rest of the code in
the switch block.
The default Keyword
The default keyword is optional and specifies some code to run if there is no case match:

Example
int day = 4;
switch (day)
{
case 6:
Console.WriteLine("Today is Saturday.");
break;
case 7:
Console.WriteLine("Today is Sunday.");
break;
default:
Console.WriteLine("Looking forward to the Weekend.");
break;
}
// Outputs "Looking forward to the Weekend."

Loops
Loops can execute a block of code as long as a specified condition is reached.
Loops are handy because they save time, reduce errors, and they make code more readable.
C# While Loop
The while loop loops through a block of code as long as a specified condition is True:

Syntax
while (condition)
{
// code block to be executed
}

In the example below, the code in the loop will run, over and over again, as long as a variable (i) is
less than 5:

Example
int i = 0;
while (i < 5)
{
Console.WriteLine(i);
i++;
}

pg. 11
C# ( Sharp ) Complete Notes

Note: Do not forget to increase the variable used in the condition, otherwise the loop will never end!

The Do/While Loop


The do/while loop is a variant of the while loop. This loop will execute the code block once, before
checking if the condition is true, then it will repeat the loop as long as the condition is true.
Syntax
do
{
// code block to be executed
}
while (condition);
The example below uses a do/while loop. The loop will always be executed at least once, even if the
condition is false, because the code block is executed before the condition is tested:
Example
int i = 0;
do
{
Console.WriteLine(i);
i++;
}

while (i < 5);

Do not forget to increase the variable used in the condition, otherwise the loop will never end!

C# For Loop
When you know exactly how many times you want to loop through a block of code, use the for loop
instead of a while loop:
Syntax
for (statement 1; statement 2; statement 3)
{
// code block to be executed
}
Statement 1 is executed (one time) before the execution of the code block.
Statement 2 defines the condition for executing the code block.
Statement 3 is executed (every time) after the code block has been executed.
The example below will print the numbers 0 to 4:
Example
for (int i = 0; i < 5; i++)
{
Console.WriteLine(i);
}
Example explained
Statement 1 sets a variable before the loop starts (int i = 0).
Statement 2 defines the condition for the loop to run (i must be less than 5). If the condition is true,
the loop will start over again, if it is false, the loop will end.
Statement 3 increases a value (i++) each time the code block in the loop has been executed.
Another Example
This example will only print even values between 0 and 10:
Example
for (int i = 0; i <= 10; i = i + 2)
{
Console.WriteLine(i);
}
Nested Loops
It is also possible to place a loop inside another loop. This is called a nested loop.
The "inner loop" will be executed one time for each iteration of the "outer loop":
Example
// Outer loop
for (int i = 1; i <= 2; ++i)
pg. 12
C# ( Sharp ) Complete Notes

{
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)
}
}

The 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
}

The following example outputs all elements in the cars array, using a foreach loop:

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

C# Break
You have already seen the break statement used in an earlier chapter of this tutorial. It was used to
"jump out" of a switch statement.
The break statement can also be used to jump out of a loop.
This example jumps out of the loop when i is equal to 4:
Example
for (int i = 0; i < 10; i++)
{
if (i == 4)
{
break;
}
Console.WriteLine(i);
}

C# Continue

The continue statement breaks one iteration (in the loop), if a specified condition occurs, and continues with the next
iteration in the loop.

This example skips the value of 4:


Example
for (int i = 0; i < 10; i++)
{
if (i == 4)
{
continue;
}
Console.WriteLine(i);
}

Break and Continue in While Loop


pg. 13
C# ( Sharp ) Complete Notes

You can also use break and continue in while loops:


Break Example
int i = 0;
while (i < 10)
{
Console.WriteLine(i);
i++;
if (i == 4)
{
break;
}
}

Continue Example
int i = 0;
while (i < 10)
{
if (i == 4)
{
i++;
continue;
}
Console.WriteLine(i);
i++;
}

C# Arrays
Create an Array
Arrays are used to store multiple values in a single variable, instead of declaring separate variables for each value.
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.
This statement accesses the value of the first element in cars:
Example
string[] cars = {"Volvo", "BMW", "Ford", "Mazda"};
Console.WriteLine(cars[0]);
// Outputs Volvo
Note: Array indexes start with 0: [0] is the first element. [1] is the second element, etc.
Change an Array Element
To change the value of a specific element, refer to the index number:
Example
cars[0] = "Opel";
Example
string[] cars = {"Volvo", "BMW", "Ford", "Mazda"};
cars[0] = "Opel";
Console.WriteLine(cars[0]);
// Now outputs Opel instead of Volvo
Array Length
To find out how many elements an array has, use the Length property:
Example
string[] cars = {"Volvo", "BMW", "Ford", "Mazda"};
Console.WriteLine(cars.Length);
// Outputs 4
Other Ways to Create an Array
pg. 14
C# ( Sharp ) Complete Notes

If you are familiar with C#, you might have seen arrays created with the new keyword, and perhaps you have seen arrays with a
specified size as well. In C#, there are different ways to create an array:
// Create an array of four elements, and add values later
string[] cars = new string[4];

It is up to you which option you choose. In our tutorial, we will often use the last option, as it is faster and easier to read.
However, you should note that if you declare an array and initialize it later, you have to use the new keyword:

C# Loop Through Arrays

Loop Through an Array

You can loop through the array elements with the for loop, and use the Length property to specify how
many times the loop should run.

The following example outputs all elements in the cars array:

Example
string[] cars = {"Volvo", "BMW", "Ford", "Mazda"};
for (int i = 0; i < cars.Length; i++)
{
Console.WriteLine(cars[i]);
}

The 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
}

C# Sort Arrays

Sort an Array

There are many array methods available, for example Sort(), which sorts an array alphabetically or in
an ascending order:
Example
// Sort a string
string[] cars = {"Volvo", "BMW", "Ford", "Mazda"};

Array.Sort(cars);
foreach (string i in cars)
{
Console.WriteLine(i);
}

// Sort an int
int[] myNumbers = {5, 1, 8, 9};

Array.Sort(myNumbers);
foreach (int i in myNumbers)
{
Console.WriteLine(i);
}

System.Linq Namespace

pg. 15
C# ( Sharp ) Complete Notes

Other useful array methods, such as Min, Max, and Sum, can be found in the System.Linq namespace:
Example
using System;
using System.Linq;

namespace MyApplication
{
class Program
{
static void Main(string[] args)
{
int[] myNumbers = {5, 1, 8, 9};
Console.WriteLine(myNumbers.Max()); // returns the largest value
Console.WriteLine(myNumbers.Min()); // returns the smallest value
Console.WriteLine(myNumbers.Sum()); // returns the sum of elements
}
}
}

C# Multidimensional Arrays

Multidimensional Arrays
you learned about arrays, which is also known as single dimension arrays. These are great, and
something you will use a lot while programming in C#. However, 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.
A multidimensional array is basically an array of arrays.
Arrays can have any number of dimensions. The most common are two-dimensional arrays (2D).
Two-Dimensional Arrays
To create a 2D array, add each array within its own set of curly braces, and insert a comma (,) inside
the square brackets:

Example
int[,] numbers = { {1, 4, 2}, {3, 6, 8} };
Good to know: The single comma [,] specifies that the array is two-dimensional. A three-dimensional
array would have two commas: int[,,].
numbers is now an array with two arrays as its elements. The first array element contains three
elements: 1, 4 and 2, while the second array element contains 3, 6 and 8. To visualize it, think of the
array as a table with rows and columns:
Access Elements of a 2D Array
To access an element of a two-dimensional array, you must specify two indexes: one for the array, and
one for the element inside that array. Or better yet, with the table visualization in mind; one for the
row and one for the column (see example below).
This statement accesses the value of the element in the first row (0) and third column (2) of
the numbers array:
Example
int[,] numbers = { {1, 4, 2}, {3, 6, 8} };
Console.WriteLine(numbers[0, 2]); // Outputs 2
Remember that: Array indexes start with 0: [0] is the first element. [1] is the second element, etc.
Change Elements of a 2D Array
You can also change the value of an element.

C# 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 reuse code: define the code once, and use it many times.

Example
Create a method inside the Program class:
pg. 16
C# ( Sharp ) Complete Notes

class Program
{
static void MyMethod()
{
// code to be executed
}
}

Example Explained
 MyMethod() 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 later in this
tutorial.
 void means that this method does not have a return value. You will learn more about return
values later in this chapter
Note: In C#, it is good practice to start with an uppercase letter when naming methods, as it makes
the code easier to read.

Call a Method
To call (execute) a method, write the method's name followed by two parentheses () and a semicolon;
In the following example, MyMethod() is used to print a text (the action), when it is called:
Example
Inside Main(), call the myMethod() method:
static void MyMethod()
{
Console.WriteLine("I just got executed!");
}

static void Main(string[] args)


{
MyMethod();
}

// Outputs "I just got executed!"

C# Method Parameters

Parameters and Arguments


Information can be passed to methods as parameter. Parameters act as variables inside the method.
They are specified after the method name, inside the parentheses. You can add as many parameters
as you want, just separate them with a comma.
The following example has a 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:
Example
static void MyMethod(string fname)
{
Console.WriteLine(fname + " Refsnes");
}

static void Main(string[] args)


{
MyMethod("RAshid");
MyMethod("Saad");
MyMethod("Hassan");
}

// Rashid Refsnes
// Saad Refsnes
// Hassan Refsnes

pg. 17
C# ( Sharp ) Complete Notes

When a parameter is passed to the method, it is called an argument. So, from the example
above: fname is a parameter, while Liam, Jenny and Anja are arguments.

Note that when you are working with multiple parameters, the method call must have the same
number of arguments as there are parameters, and the arguments must be passed in the same order.

C# Default Parameter Value


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 ("Norway"):

Example
static void MyMethod(string country = "Norway")
{
Console.WriteLine(country);
}

static void Main(string[] args)


{
MyMethod("Sweden");
MyMethod("Pakistan");
MyMethod();
MyMethod("USA");
}

C# Return Values

Return Values
we used the void keyword in all examples, which indicates that the method should not return a value.
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:
Example
static int MyMethod(int x)
{
return 5 + x;
}

static void Main(string[] args)


{
Console.WriteLine(MyMethod(3));
}

// Outputs 8 (5 + 3)

C# Named Arguments

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: "Rashid", child1: "Hassan", child2: "Saad");
}
// The youngest child is: Rashid
pg. 18
C# ( Sharp ) Complete Notes

C# Method Overloading

Method Overloading
With method overloading, multiple methods can have the same name with different parameters:

Example
int MyMethod(int x)
float MyMethod(float x)
double MyMethod(double x, double y)
Consider the following example, which have two methods that add numbers of different type:

# OOP

C# - What is OOP?

OOP stands for Object-Oriented Programming.

Procedural programming is about writing procedures or methods that perform operations on the data,
while object-oriented programming is about creating objects that contain both data and methods.

Object-oriented programming has several advantages over procedural programming:

 OOP is faster and easier to execute


 OOP provides a clear structure for the programs
 OOP helps to keep the C# code DRY "Don't Repeat Yourself", and makes the code easier to
maintain, modify and debug
 OOP makes it possible to create full reusable applications with less code and shorter
development time

Tip: The "Don't Repeat Yourself" (DRY) principle is about reducing the repetition of code. You should
extract out the codes that are common for the application, and place them at a single place and reuse
them instead of repeating it.

C# - What are Classes and Objects?

Classes and objects are the two main aspects of object-oriented programming.

Look at the following illustration to see the difference between class and objects:

pg. 19
C# ( Sharp ) Complete Notes

Another Example

So, a class is a template for objects, and an object is an instance of a class.

When the individual objects are created, they inherit all the variables and methods from the class.

C# Classes and Objects

Classes and Objects


Everything in C# is associated with classes and objects, along with its attributes and methods. For
example: in real life, a car is an object. The car has attributes, such as weight and color,
and methods, such as drive and brake.
A Class is like an object constructor, or a "blueprint" for creating objects.

Create a Class
To create a class, use the class keyword:

Create a class named "Car" with a variable color:


class Car
{
string color = "red";
}

When a variable is declared directly in a class, it is often referred to as a field (or attribute).
It is not required, but it is a good practice to start with an uppercase first letter when naming classes.
Also, it is common that the name of the C# file and the class matches, as it makes our code organized.
However it is not required (like in Java).

Create an Object
An object is created from a class. We have already created the class named Car, so now we can use
this to create objects.
To create an object of Car, specify the class name, followed by the object name, and use the
keyword new:
Example
Create an object called "myObj" and use it to print the value of color:
class Car
{
string color = "red";

static void Main(string[] args)


{
Car myObj = new Car();
Console.WriteLine(myObj.color);
}
}
Note that we use the dot syntax (.) to access variables/fields inside a class (myObj.color).

C# Multiple Classes and Objects

Multiple Objects
You can create multiple objects of one class:
Example
Create two objects of Car:
class Car
pg. 20
C# ( Sharp ) Complete Notes

{
string color = "red";
static void Main(string[] args)
{
Car myObj1 = new Car();
Car myObj2 = new Car();
Console.WriteLine(myObj1.color);
Console.WriteLine(myObj2.color);
}
}
Using Multiple Classes
You can also create an object of a class and access it in another class. This is often used for better
organization of classes (one class has all the fields and methods, while the other class holds
the Main() method (code to be executed)).
 prog2.cs
 prog.cs
prog2.cs
class Car
{
public string color = "red";
}
prog.cs
class Program
{
static void Main(string[] args)
{
Car myObj = new Car();
Console.WriteLine(myObj.color);
}
}
Did you notice the public keyword? It is called an access modifier, which specifies that
the color variable/field of Car is accessible for other classes as well, such as Program.

C# Class Members
Class Members
Fields and methods inside classes are often referred to as "Class Members":
Example
Create a Car class with three class members: two fields and one method.
// The class
class MyClass
{
// Class members
string color = "red"; // field
int maxSpeed = 200; // field
public void fullThrottle() // method
{
Console.WriteLine("The car is going as fast as it can!");
}
}

Fields
In the previous chapter, you learned that variables inside a class are called fields, and that you can
access them by creating an object of the class, and by using the dot syntax (.).
The following example will create an object of the Car class, with the name myObj. Then we print the
value of the fields color and maxSpeed:

pg. 21
C# ( Sharp ) Complete Notes

Example
class Car
{
string color = "red";
int maxSpeed = 200;

static void Main(string[] args)


{
Car myObj = new Car();
Console.WriteLine(myObj.color);
Console.WriteLine(myObj.maxSpeed);
}
}
You can also leave the fields blank, and modify them when creating the object:
Example
class Car
{
string color;
int maxSpeed;

static void Main(string[] args)


{
Car myObj = new Car();
myObj.color = "red";
myObj.maxSpeed = 200;
Console.WriteLine(myObj.color);
Console.WriteLine(myObj.maxSpeed);
}
}
This is especially useful when creating multiple objects of one class:
Example
class Car
{
string model;
string color;
int year;

static void Main(string[] args)


{
Car Ford = new Car();
Ford.model = "Mustang";
Ford.color = "red";
Ford.year = 1969;

Car Opel = new Car();


Opel.model = "Astra";
Opel.color = "white";
Opel.year = 2005;

Console.WriteLine(Ford.model);
Console.WriteLine(Opel.model);
}
}
Object Methods
You learned from the C# Methods chapter that methods are used to perform certain actions.
Methods normally belong to a class, and they define how an object of a class behaves.
Just like with fields, you can access methods with the dot syntax. However, note that the method must
be public. And remember that we use the name of the method followed by two parentheses () and a
semicolon ; to call (execute) the method:
Example
class Car
pg. 22
C# ( Sharp ) Complete Notes

{
string color; // field
int maxSpeed; // field
public void fullThrottle() // method
{
Console.WriteLine("The car is going as fast as it can!");
}

static void Main(string[] args)


{
Car myObj = new Car();
myObj.fullThrottle(); // Call the method
}
}
Why did we declare the method as public, and not static,
The reason is simple: a static method can be accessed without creating an object of the class,
while public methods can only be accessed by objects.
Use Multiple Classes
Remember from the last chapter, that we can use multiple classes for better organization (one for
fields and methods, and another one for execution). This is recommended:
prog2.cs
class Car
{
public string model;
public string color;
public int year;
public void fullThrottle()
{
Console.WriteLine("The car is going as fast as it can!");
}
}
prog.cs
class Program
{
static void Main(string[] args)
{
Car Ford = new Car();
Ford.model = "Mustang";
Ford.color = "red";
Ford.year = 1969;

Car Opel = new Car();


Opel.model = "Astra";
Opel.color = "white";
Opel.year = 2005;
Console.WriteLine(Ford.model);
Console.WriteLine(Opel.model);
}
}
The public keyword is called an access modifier, which specifies that the fields of Car are accessible
for other classes as well, such as Program.

C# Constructors

Constructors

A constructor is a special method that is used to initialize objects. The advantage of a constructor, is
that it is called when an object of a class is created. It can be used to set initial values for fields:
Example
Create a constructor:
pg. 23
C# ( Sharp ) Complete Notes

// Create a Car class


class Car
{
public string model; // Create a field
// Create a class constructor for the Car class
public Car()
{
model = "Mustang"; // Set the initial value for model
}
static void Main(string[] args)
{
Car Ford = new Car(); // Create an object of the Car Class (this will call the
constructor)
Console.WriteLine(Ford.model); // Print the value of model
}
}
// Outputs "Mustang"

Note that the constructor name must match the class name, and it cannot have a return
type (like void or int).

Also note that the constructor is called when the object is created.

All classes have constructors by default: if you do not create a class constructor yourself, C# creates
one for you. However, then you are not able to set initial values for fields.

Constructor Parameters

Constructors can also take parameters, which is used to initialize fields.

The following example adds a string modelName parameter to the constructor. Inside the constructor
we set model to modelName (model=modelName). When we call the constructor, we pass a parameter to
the constructor ("Mustang"), which will set the value of model to "Mustang":
Example
class Car
{
public string model;

// Create a class constructor with a parameter


public Car(string modelName)
{
model = modelName;
}

static void Main(string[] args)


{
Car Ford = new Car("Mustang");
Console.WriteLine(Ford.model);
}
}
// Outputs "Mustang"
You can have as many parameters as you want:
Example
class Car
{
public string model;
public string color;
public int year;

// Create a class constructor with multiple parameters


pg. 24
C# ( Sharp ) Complete Notes

public Car(string modelName, string modelColor, int modelYear)


{
model = modelName;
color = modelColor;
year = modelYear;
}

static void Main(string[] args)


{
Car Ford = new Car("Mustang", "Red", 1969);
Console.WriteLine(Ford.color + " " + Ford.year + " " + Ford.model);
}
}
// Outputs Red 1969 Mustang

Tip: Just like other methods, constructors can be overloaded by using different numbers of
parameters.

Constructors Save Time


When you consider the example from the previous chapter, you will notice that constructors are very
useful, as they help reducing the amount of code:
Without constructor:
prog.cs
class Program
{
static void Main(string[] args)
{
Car Ford = new Car();
Ford.model = "Mustang";
Ford.color = "red";
Ford.year = 1969;

Car Opel = new Car();


Opel.model = "Astra";
Opel.color = "white";
Opel.year = 2005;

Console.WriteLine(Ford.model);
Console.WriteLine(Opel.model);
}
}
With constructor:
prog.cs
class Program
{
static void Main(string[] args)
{
Car Ford = new Car("Mustang", "Red", 1969);
Car Opel = new Car("Astra", "White", 2005);

Console.WriteLine(Ford.model);
Console.WriteLine(Opel.model);
}
}

C# Access Modifiers

Access Modifiers

By now, you are quite familiar with the public keyword that appears in many of our examples:

pg. 25
C# ( Sharp ) Complete Notes

public string color;

The public keyword is an access modifier, which is used to set the access level/visibility for classes,
fields, methods and properties.

C# has the following access modifiers:


Modifier Description

public The code is accessible for all classes

private The code is only accessible within the same class

protected The code is accessible within the same class, or in a class that is inherited from that class. You will learn
more about inheritance in a later chapter

internal The code is only accessible within its own assembly, but not from another assembly. You will learn more
about this in a later chapter
There's also two combinations: protected internal and private protected.
For now, lets focus on public and private modifiers.
Private Modifier
If you declare a field with a private access modifier, it can only be accessed within the same class:
Example
class Car
{
private string model = "Mustang";

static void Main(string[] args)


{
Car myObj = new Car();
Console.WriteLine(myObj.model);
}
}
The output will be:
Mustang
If you try to access it outside the class, an error will occur:
Example
class Car
{
private string model = "Mustang";
}

class Program
{
static void Main(string[] args)
{
Car myObj = new Car();
Console.WriteLine(myObj.model);
}
}

The output will be:


'Car.model' is inaccessible due to its protection level
The field 'Car.model' is assigned but its value is never used

Public Modifier
If you declare a field with a public access modifier, it is accessible for all classes:

pg. 26
C# ( Sharp ) Complete Notes

Example
class Car
{
public string model = "Mustang";
}

class Program
{
static void Main(string[] args)
{
Car myObj = new Car();
Console.WriteLine(myObj.model);
}
}

The output will be:


Mustang

Why Access Modifiers?


To control the visibility of class members (the security level of each individual class and class
member).
To achieve "Encapsulation" - which is the process of making sure that "sensitive" data is hidden from
users. This is done by declaring fields as private. You will learn more about this in the next chapter.
Note: By default, all members of a class are private if you don't specify an access modifier:
Example
class Car
{
string model; // private
string year; // private
}

C# Properties (Get and Set)

Properties and Encapsulation


Before we start to explain properties, you should have a basic understanding of "Encapsulation".
The meaning of Encapsulation, is to make sure that "sensitive" data is hidden from users. To achieve
this, you must:
 declare fields/variables as private
 provide public get and set methods, through properties, to access and update the value of
a private field
Properties
You learned from the previous chapter that private variables can only be accessed within the same
class (an outside class has no access to it). However, sometimes we need to access them - and it can
be done with properties.
A property is like a combination of a variable and a method, and it has two methods: a get and
a set method:
Example
class Person
{
private string name; // field

public string Name // property


{
get { return name; } // get method
set { name = value; } // set method
}
}

pg. 27
C# ( Sharp ) Complete Notes

Example explained
The Name property is associated with the name field. It is a good practice to use the same name for both
the property and the private field, but with an uppercase first letter.
The get method returns the value of the variable name.
The set method assigns a value to the name variable. The value keyword represents the value we
assign to the property.
If you don't fully understand it, take a look at the example below.
Now we can use the Name property to access and update the private field of the Person class:
Example
class Person
{
private string name; // field
public string Name // property
{
get { return name; }
set { name = value; }
}
}

class Program
{
static void Main(string[] args)
{
Person myObj = new Person();
myObj.Name = "Rashid";
Console.WriteLine(myObj.Name);
}
}
The output will be:
Rashid

Automatic Properties (Short Hand)


C# also provides a way to use short-hand / automatic properties, where you do not have to define the
field for the property, and you only have to write get; and set; inside the property.
The following example will produce the same result as the example above. The only difference is that
there is less code:
Example
Using automatic properties:
class Person
{
public string Name // property
{ get; set; }
}

class Program
{
static void Main(string[] args)
{
Person myObj = new Person();
myObj.Name = "Rashid";
Console.WriteLine(myObj.Name);
}
}
The output will be:
Rashid

Why Encapsulation?

pg. 28
C# ( Sharp ) Complete Notes

 Better control of class members (reduce the possibility of yourself (or others) to mess up the
code)
 Fields can be made read-only (if you only use the get method), or write-only (if you only use
the set method)
 Flexible: the programmer can change one part of the code without affecting other parts
 Increased security of data

C# Inheritance

Inheritance (Derived and Base Class)


In C#, it is possible to inherit fields and methods from one class to another. We group the "inheritance
concept" into two categories:
 Derived Class (child) - the class that inherits from another class
 Base Class (parent) - the class being inherited from
To inherit from a class, use the : symbol.
In the example below, the Car class (child) inherits the fields and methods from the Vehicle class
(parent):
Example
class Vehicle // base class (parent)
{
public string brand = "Ford"; // Vehicle field
public void honk() // Vehicle method
{
Console.WriteLine("Tuut, tuut!");
}
}

class Car : Vehicle // derived class (child)


{
public string modelName = "Mustang"; // Car field
}

class Program
{
static void Main(string[] args)
{
// Create a myCar object
Car myCar = new Car();

// Call the honk() method (From the Vehicle class) on the myCar object
myCar.honk();

// Display the value of the brand field (from the Vehicle class) and the value of the
modelName from the Car class
Console.WriteLine(myCar.brand + " " + myCar.modelName);
}
}

Why And When To Use "Inheritance"?


- It is useful for code reusability: reuse fields and methods of an existing class when you create a new
class.
Tip: Also take a look at the next chapter, Polymorphism, which uses inherited methods to perform
different tasks.
The sealed Keyword
If you don't want other classes to inherit from a class, use the sealed keyword:
If you try to access a sealed class, C# will generate an error:
sealed class Vehicle
pg. 29
C# ( Sharp ) Complete Notes

{
...
}

class Car : Vehicle


{
...
}
The error message will be something like this:
'Car': cannot derive from sealed type 'Vehicle'

C# Polymorphism

Polymorphism and Overriding Methods


Polymorphism means "many forms", and it occurs when we have many classes that are related to each
other by inheritance.
Like we specified in the previous chapter; Inheritance lets us inherit fields and methods from another
class. Polymorphism uses those methods to perform different tasks. This allows us to perform a
single action in different ways.
For example, think of a base class called Animal that has a method called animalSound(). Derived
classes of Animals could be Pigs, Cats, Dogs, Birds - And they also have their own implementation of
an animal sound (the pig oinks, and the cat meows, etc.):
Example
class Animal // Base class (parent)
{
public void animalSound()
{
Console.WriteLine("The animal makes a sound");
}
}

class Pig : Animal // Derived class (child)


{
public void animalSound()
{
Console.WriteLine("The pig says: wee wee");
}
}

class Dog : Animal // Derived class (child)


{
public void animalSound()
{
Console.WriteLine("The dog says: bow wow");
}
}

Remember from the Inheritance chapter that we use the : symbol to inherit from a class.
Now we can create Pig and Dog objects and call the animalSound() method on both of them:
Example
class Animal // Base class (parent)
{
public void animalSound()
{
Console.WriteLine("The animal makes a sound");
}
}

pg. 30
C# ( Sharp ) Complete Notes

class Pig : Animal // Derived class (child)


{
public void animalSound()
{
Console.WriteLine("The pig says: wee wee");
}
}

class Dog : Animal // Derived class (child)


{
public void animalSound()
{
Console.WriteLine("The dog says: bow wow");
}
}

class Program
{
static void Main(string[] args)
{
Animal myAnimal = new Animal(); // Create a Animal object
Animal myPig = new Pig(); // Create a Pig object
Animal myDog = new Dog(); // Create a Dog object

myAnimal.animalSound();
myPig.animalSound();
myDog.animalSound();
}
}

The output will be:


The animal makes a sound
The animal makes a sound
The animal makes a sound

Not The Output I Was Looking For


The output from the example above was probably not what you expected. That is because the base
class method overrides the derived class method, when they share the same name.
However, C# provides an option to override the base class method, by adding the virtual keyword to
the method inside the base class, and by using the override keyword for each derived class methods:
Example
class Animal // Base class (parent)
{
public virtual void animalSound()
{
Console.WriteLine("The animal makes a sound");
}
}

class Pig : Animal // Derived class (child)


{
public override void animalSound()
{
Console.WriteLine("The pig says: wee wee");
}
}

class Dog : Animal // Derived class (child)

pg. 31
C# ( Sharp ) Complete Notes

{
public override void animalSound()
{
Console.WriteLine("The dog says: bow wow");
}
}

class Program
{
static void Main(string[] args)
{
Animal myAnimal = new Animal(); // Create a Animal object
Animal myPig = new Pig(); // Create a Pig object
Animal myDog = new Dog(); // Create a Dog object

myAnimal.animalSound();
myPig.animalSound();
myDog.animalSound();
}
}
The output will be:
The animal makes a sound
The pig says: wee wee
The dog says: bow wow

Why And When To Use "Inheritance" and "Polymorphism"?


- It is useful for code reusability: reuse fields and methods of an existing class when you create a new
class.

C# Abstraction

Abstract Classes and Methods


Data abstraction is the process of hiding certain details and showing only essential information to the
user.
Abstraction can be achieved with either abstract classes or interfaces (which you will learn more
about in the next chapter).
The abstract keyword is used for classes and methods:
 Abstract class: is a restricted class that cannot be used to create objects (to access it, it must
be inherited from another class).

 Abstract method: can only be used in an abstract class, and it does not have a body. The
body is provided by the derived class (inherited from).
An abstract class can have both abstract and regular methods:
abstract class Animal
{
public abstract void animalSound();
public void sleep()
{
Console.WriteLine("Zzz");
}
}
From the example above, it is not possible to create an object of the Animal class:
Animal myObj = new Animal(); // Will generate an error (Cannot create an instance of the
abstract class or interface 'Animal')

To access the abstract class, it must be inherited from another class. Let's convert the Animal class we
used in the Polymorphism chapter to an abstract class.

pg. 32
C# ( Sharp ) Complete Notes

Remember from the Inheritance chapter that we use the : symbol to inherit from a class, and that we
use the override keyword to override the base class method.

Example
// Abstract class
abstract class Animal
{
// Abstract method (does not have a body)
public abstract void animalSound();
// Regular method
public void sleep()
{
Console.WriteLine("Zzz");
}
}

// Derived class (inherit from Animal)


class Pig : Animal
{
public override void animalSound()
{
// The body of animalSound() is provided here
Console.WriteLine("The pig says: wee wee");
}
}

class Program
{
static void Main(string[] args)
{
Pig myPig = new Pig(); // Create a Pig object
myPig.animalSound(); // Call the abstract method
myPig.sleep(); // Call the regular method
}
}
Why And When To Use Abstract Classes and Methods?
To achieve security - hide certain details and only show the important details of an object.
Note: Abstraction can also be achieved with Interfaces

C# Interface

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):
Example
// interface
interface Animal
{
void animalSound(); // interface method (does not have a body)
void run(); // interface method (does not have a body)
}

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.
By default, members of an interface are abstract and public.
Note: Interfaces can contain properties and methods, but not fields.

pg. 33
C# ( Sharp ) Complete Notes

To access the interface methods, the interface must be "implemented" (kinda like inherited) by another
class. To implement an interface, use the : symbol (just like with inheritance). The body of the
interface method is provided by the "implement" class. Note that you do not have to use
the override keyword when implementing an interface:

Example
// Interface
interface IAnimal
{
void animalSound(); // interface method (does not have a body)
}

// Pig "implements" the IAnimal interface


class Pig : IAnimal
{
public void animalSound()
{
// The body of animalSound() is provided here
Console.WriteLine("The pig says: wee wee");
}
}

class Program
{
static void Main(string[] args)
{
Pig myPig = new Pig(); // Create a Pig object
myPig.animalSound();
}
}

Notes on Interfaces:
 Like abstract classes, interfaces cannot be used to create objects (in the example above, it is
not possible to create an "IAnimal" object in the Program class)
 Interface methods do not have a body - the body is provided by the "implement" class
 On implementation of an interface, you must override all of its methods
 Interfaces can contain properties and methods, but not fields/variables
 Interface members are by default abstract and public
 An interface cannot contain a constructor (as it cannot be used to create objects)
Why And When To Use Interfaces?
1) To achieve security - hide certain details and only show the important details of an object
(interface).
2) C# does not support "multiple inheritance" (a class can only inherit from one base class). However,
it can be achieved with interfaces, because the class can implement multiple interfaces. Note: To
implement multiple interfaces, separate them with a comma (see example below).

Multiple Interfaces

To implement multiple interfaces, separate them with a comma:


Example
interface IFirstInterface
{
void myMethod(); // interface method
}

interface ISecondInterface
{
void myOtherMethod(); // interface method
}

pg. 34
C# ( Sharp ) Complete Notes

// Implement multiple interfaces


class DemoClass : IFirstInterface, ISecondInterface
{
public void myMethod()
{
Console.WriteLine("Some text..");
}
public void myOtherMethod()
{
Console.WriteLine("Some other text...");
}
}
class Program
{
static void Main(string[] args)
{
DemoClass myObj = new DemoClass();
myObj.myMethod();
myObj.myOtherMethod();
}
}

C# Enums
An enum is a special "class" that represents a group of constants (unchangeable/read-only variables).
To create an enum, use the enum keyword (instead of class or interface), and separate the enum items
with a comma:
Example
enum Level
{
Low,
Medium,
High
}
You can access enum items with the dot syntax:
Level myVar = Level.Medium;
Console.WriteLine(myVar);

Enum is short for "enumerations", which means "specifically listed".

Enum inside a Class


You can also have an enum inside a class:
Example
class Program
{
enum Level
{
Low,
Medium,
High
}
static void Main(string[] args)
{
Level myVar = Level.Medium;
Console.WriteLine(myVar);
}
}
The output will be:
Medium

pg. 35
C# ( Sharp ) Complete Notes

Enum Values
By default, the first item of an enum has the value 0. The second has the value 1, and so on.
To get the integer value from an item, you must explicitly convert the item to an int:

Example
enum Months
{
January, // 0
February, // 1
March, // 2
April, // 3
May, // 4
June, // 5
July // 6
}

static void Main(string[] args)


{
int myNum = (int) Months.April;
Console.WriteLine(myNum);
}
The output will be:
3
You can also assign your own enum values, and the next items will update their numbers accordingly:
Example
enum Months
{
January, // 0
February, // 1
March=6, // 6
April, // 7
May, // 8
June, // 9
July // 10
}

static void Main(string[] args)


{
int myNum = (int) Months.April;
Console.WriteLine(myNum);
}
The output will be:
7

Enum in a Switch Statement


Enums are often used in switch statements to check for corresponding values:
Example
enum Level
{
Low,
Medium,
pg. 36
C# ( Sharp ) Complete Notes

High
}

static void Main(string[] args)


{
Level myVar = Level.Medium;
switch(myVar)
{
case Level.Low:
Console.WriteLine("Low level");
break;
case Level.Medium:
Console.WriteLine("Medium level");
break;
case Level.High:
Console.WriteLine("High level");
break;
}
}
The output will be:
Medium level
Why And When To Use Enums?
Use enums when you have values that you know aren't going to change, like month days, days, colors,
deck of cards, etc.

C# Exceptions - Try..Catch

C# Exceptions
When executing C# code, different errors can occur: coding errors made by the programmer, errors
due to wrong input, or other unforeseeable things.
When an error occurs, C# will normally stop and generate an error message. The technical term for
this is: C# will throw an exception (throw an error).

C# try and catch


The try statement allows you to define a block of code to be tested for errors while it is 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:

Syntax
try
{
// Block of code to try
}
catch (Exception e)
{
// Block of code to handle errors
}

Consider the following example, where we create an array of three integers:

This will generate an error, because myNumbers[10] does not exist.


int[] myNumbers = {1, 2, 3};
Console.WriteLine(myNumbers[10]); // error!
The error message will be something like this:
System.IndexOutOfRangeException: 'Index was outside the bounds of the array.'
If an error occurs, we can use try...catch to catch the error and execute some code to handle it.

pg. 37
C# ( Sharp ) Complete Notes

In the following example, we use the variable inside the catch block (e) together with the built-
in Message property, which outputs a message that describes the exception:
Example
try
{
int[] myNumbers = {1, 2, 3};
Console.WriteLine(myNumbers[10]);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
The output will be:
Index was outside the bounds of the array.

You can also output your own error message:

Example
try
{
int[] myNumbers = {1, 2, 3};
Console.WriteLine(myNumbers[10]);
}
catch (Exception e)
{
Console.WriteLine("Something went wrong.");
}
The output will be:
Something went wrong.

Finally
The finally statement lets you execute code, after try...catch, regardless of the result:
Example
try
{
int[] myNumbers = {1, 2, 3};
Console.WriteLine(myNumbers[10]);
}
catch (Exception e)
{
Console.WriteLine("Something went wrong.");
}
finally
{
Console.WriteLine("The 'try catch' is finished.");
}
The output will be:
Something went wrong.
The 'try catch' is finished.

The throw keyword


The throw statement allows you to create a custom error.
The throw statement is used together with an exception class. There are many exception classes
available in
C#: ArithmeticException, FileNotFoundException, IndexOutOfRangeException, TimeOutException, etc:
Example
static void checkAge(int age)
{
if (age < 18)
{

pg. 38
C# ( Sharp ) Complete Notes

throw new ArithmeticException("Access denied - You must be at least 18 years old.");


}
else
{
Console.WriteLine("Access granted - You are old enough!");
}
}

static void Main(string[] args)


{
checkAge(15);
}
The error message displayed in the program will be:
System.ArithmeticException: 'Access denied - You must be at least 18 years old.'

If age was 20, you would not get an exception:


Example
checkAge(20);
The output will be:
Access granted - You are old enough!

Introduction to Event

Events are a way for an object to broadcast (to all interested components in the system) that something has
happened. Any other component can subscribe to the event, and be notified when an event is raised.

You've probably used events in some of your programming. Many graphical systems have an event model to report
user interaction. These events would report mouse movement, button presses and similar interactions. That's one of
the most common, but certainly not the only scenario where events are used.
Declaration of the Event
Syntax

public event EventHandler CellEvent;


Steps for implementing the Event

For the declaration of the Event in the class, firstly, the event type of the delegate must be declared.

public delegate void CellEventHandler(object sender, EventArgs e);


Declaration of the Event

public event CellEventHandler CellEvent;


Invokation of the Event

if (CellEvent != null) CellEvent(this, e);

We can invoke the Event only from within the class where we declared the Event.

fundamental of event-driven programming

Event-driven programming (EDP) is a programming paradigm where external events determine the flow of program
execution. These events come in different shapes: user actions (e.g., button clicks, keyboard inputs), system events
(like a finished file download), messages from other programs, sensor outputs, etc.

message handling in visual programming

pg. 39
C# ( Sharp ) Complete Notes

The basic idea of message handlers is that the class receives messages of some sort and dispatches them, calling
one of a set of specified methods depending on the message received. If no specific method exists for a particular
message, there is a default handler.

User Interface

graphical user interface (GUI) framework that enables developers to create desktop applications for the Windows
operating system.
Graphics Device Interface
The Graphics Device Interface (GDI) is a Microsoft Windows application programming interface and core operating
system component responsible for representing graphical objects and transmitting them to output devices such
as monitors and printers.

GDI is responsible for tasks such as drawing lines and curves, rendering fonts and handling palettes. It is not directly
responsible for drawing windows, menus, etc.; that task is reserved for the user subsystem, which resides in
user32.dll and is built atop GDI. GDI is similar to Macintosh's QuickDraw and GNOME/GTK's GDK/Xlib.

Print and Drawing


C# provides an amazingly powerful array of drawing capabilities. However, this power comes at the price of a steep
learning curve. Drawing isn't intuitive; you can't sit down for a few minutes with the online Help text and start drawing
graphics. After you learn the basic principles involved, however, you'll find that drawing isn't that complicated. In this
hour, you'll learn the basic skills for drawing shapes and text to a form or other graphical surface. You'll learn about
pens, colors, and brushes. In addition, you'll learn how to persist graphics on a form—and even how to create bitmaps
that exist solely in memory.
The highlights of this hour include the following:

 Understanding the Graphics object


 Working with pens
 Using system colors
 Working with rectangles
 Drawing shapes
 Drawing text
 Persisting graphics on a form

window management
Window management deals with the management of Design Windows in the Workspace. Window management allows
for closing, resizing, and arranging of multiple simultaneously opened Design Windows within the Workspace.
Specifically, the tasks for window management are: Window Closing.

Input Devices

an input device is a piece of equipment used to provide data and control signals to an information processing system,
such as a computer or information appliance. Examples of input devices include keyboards, computer mice, scanners,
cameras, joysticks, and microphones. Duration: 35 seconds.

Resources in C#
Resources is a very useful namespace that allows you to create and store culture-specific resources used in an
application (for example, you can have Spanish and English resources). Resources allows you to place culture-
specific items inside satellite files, rather than directly in your main application.

Menu Resources
A menu resource is a collection of information that defines the appearance and function of an application menu. A
menu is a special input tool that lets a user select commands and open submenus from a list of menu items

Dialog control in C#

A dialog box in C# is a type of window, which is used to enable common communication or dialog between a
computer and its user. A dialog box is most often used to provide the user with the means for specifying how to
implement a command or to respond to a question. Windows.

Window control in C#

pg. 40
C# ( Sharp ) Complete Notes

Controls can be added to the Windows forms C# via the Toolbox in Visual Studio. Controls such as labels,
checkboxes, radio buttons, etc
1) Windows form controls are implemented by extensible managed classes. Office controls are unmanaged.
2) Windows form controls have no concept of their location in relation to the containing workbook or document. You
can use this Controls collection to enumerate through all the controls

Common control in C#
A control is a child window an application uses in conjunction with another window to. perform simple input and output
(I/O) tasks. Controls are most often used within dialog. boxes, but they can also be used in other windows.

Common controls in this topic

 Scroll bars
 Input fields
 Combo boxes and drop-down lists
 Check boxes
 Radio buttons
 Group frames
 Text controls
 Buttons and hyperlinks
 Tree views

Visual style

The first thing to consider when styling controls is whether the controls will be used in themed UI. Controls in standard
UI are non-themed UI and must follow normal Windows Desktop style, meaning that they are not re-templated and
should appear in their default control appearance.

 Standard (utility) dialogs: not themed. Don't re-template. Use basic control style defaults.
 Tool windows, document editors, design surfaces and themed dialogs: Use specialized themed appearance
using the color service.

Scroll bars

Scroll bars should follow common interaction patterns for Windows scroll bars unless they're augmented with content
information, like in the code editor.

Input fields

For typical interaction behavior, follow the Windows Desktop guidelines for text boxes.

Visual style

 Input fields shouldn't be styled in utility dialogs. Use the basic style intrinsic to the control.
 Themed input fields should only be used in themed dialogs and tool windows.

Specialized interactions

 Read-only fields will have a gray (disabled) background but default (active) foreground.

pg. 41
C# ( Sharp ) Complete Notes

 Required fields should have <Required> as watermarks within them. You should not change the color of the
background except in rare situations.
 Error validation: See Notifications and Progress for Visual Studio
 Input fields should be sized to fit the content, not to fit the width of the window in which they are shown, nor to
arbitrarily match the length of a long field, like a path. Length might be an indication to the user of limitations
as to how many characters are allowed in the field.

Incorrect input field length: it's unlikely that the name will be this long.

Correct input field length: the input field is a reasonable width for the expected content.

Combo boxes and drop-down lists

For typical interaction behavior, follow the Windows Desktop guidelines for drop-down lists and combo boxes.

Visual style

 In utility dialogs, don't re-template the control. Use the basic style intrinsic to the control.
 In themed UI, combo boxes and drop-downs follow the standard theming for the controls.

Layout

Combo boxes and drop-downs should be sized to fit the content, not to fit the width of the window in which they are
shown, nor to arbitrarily match the length of a long field, like a path.

Incorrect: the drop-down width is too long for the content that will be displayed.

Correct: the drop-down is sized to allow for translation growth, but not unnecessarily long.

pg. 42
C# ( Sharp ) Complete Notes

Check boxes

For typical interaction behavior, follow the Windows Desktop guidelines for check boxes.

Visual style

 In utility dialogs, don't re-template the control. Use the basic style intrinsic to the control.
 In themed UI, check boxes follow the standard theming for the controls.

Specialized interactions

 Interaction with a check box must never pop a dialog or navigate to another area.
 Align check boxes with the baseline of the first line of text.

Incorrect: the check box is centered on the text.

Correct: the check box is aligned with the first line of the text.

Radio buttons

For typical interaction behavior, follow the Windows Desktop guidelines for radio buttons.

Visual style

In utility dialogs, do not style radio buttons. Use the basic style intrinsic to the control.

Specialized interactions

It's not necessary to use a group frame to enclose radio choices, unless you need to maintain group distinction in a
tight layout.

Group frames

For typical interaction behavior, follow the Windows Desktop guidelines for group frames.

Visual style

In utility dialogs, don't style group frames. Use the basic style intrinsic to the control.

pg. 43
C# ( Sharp ) Complete Notes

Layout

 It's not necessary to use a group frame to enclose radio choices, unless you need to maintain group distinction
in a tight layout.
 Never use a group frame for a single control.
 It's sometimes acceptable to use a horizontal rule instead of a group frame container.

Text controls

Static text fields

A static text field presents read-only information and cannot be selected by the user. Avoid using it for any text the
user might want to copy to the clipboard. However, read-only static text can change to reflect a change in state. In the
example below, the Output Name static text under the Information group changes to reflect any changes made to the
Root Namespace text box above it.

There are two ways to display static text information.

Static text can be on its own in a dialog without any containment when there is no grouping conflict. Decide if the
extra lines of a box are really necessary. An example is the display of a directory path under a section created by a
group line, as shown below:

Static text info in text controls

In a dialog where other grouped areas exist and containment of the information would help readability, and when a
section can be hidden or shown (as in the Properties window description pane) or you want to be consistent with
similar UI, place the static text inside a box. This group box should be a single rule and colored with
the ButtonShadow:

pg. 44
C# ( Sharp ) Complete Notes

Static text in the Properties window

Read-only text box

This allows the user to select the text inside the field but not edit it. These text boxes are bordered by the usual 3-D
chisel with a ButtonShadow fill.

A text box can become active (editable) when a user alters an associated control, such as checking/unchecking a check
box or selecting/deselecting a radio button. For example, in the Tools > Options page shown below, the Home
Page text box becomes active when the Use Default check box is unchecked.

Read-only text box, showing inactive and active states

pg. 45
C# ( Sharp ) Complete Notes

Using text in dialogs

Key guidelines for text in dialogs:

 Labels for text boxes, list boxes, and frames in unthemed dialogs start with a verb, have an initial capital on the
first word only, and end with a colon.

Text controls in themed dialogs follow Windows desktop UX guidelines and do not take end punctuation, with
the exception of question marks in Help links.

 Labels for check boxes and option buttons start with a verb, an initial capital on the first word only, and have no
ending punctuation.
 Labels for buttons, menus, menu items, and tabs have initial capitals on each word (title case).
 Label terminology should be consistent with similar labels in other dialogs.
 If possible, have a writer/editor write or approve the text before it goes to the developer for implementation.
 All controls should have labels except in special circumstances in which tabbing is sufficient. Use helper text
when appropriate.

Helper text

Included in dialogs to help the user understand the dialog's purpose or to indicate which action to take. Helper text
should be used only when needed to avoid cluttering simple dialogs. The two variations of helper text are dialog and
watermark.

Follow common locations for helper text and be selective in introducing new areas. Common scenarios for helper text
are:

 Helper text in dialogs, to give additional direction about how to interact with a complex dialog.
 Watermark text in empty tool windows or dialogs, to explain why no content is visible.
 A description pane, like at the bottom of the Properties window.
 Watermark text in an empty editor, to explain what action the user should take to get started.

Dialog helper text

A user experience designer may help determine when helper text is appropriate. The designer can define where helper
text appears as well as its general content. User assistance can write/edit the actual text.

Watermarks

Dialogs benefit from slightly different watermark guidelines. Because a dialog can appear busy with many UI elements
(labels, hint text, buttons and other container controls with text), particularly when those appear in black, watermarks
stand out better in dark gray (VSColor: ButtonShadow). Typically a watermark appears inside a control like a list box
with a white background (VSColor: Window).

 The text appears in dark gray (VSColor: ButtonShadow). However, if the watermark appears on a medium gray
or other-colored (VSColor: ButtonFace) background and there is concern about its readability, go with black
text (VSColor: WindowText).
 Watermarks can be centered or flush left. Apply standard design rules when making alignment decisions. The
watermark cannot be selected on the background.

pg. 46
C# ( Sharp ) Complete Notes

Watermark text example

Context-specific (dynamic) text

Dynamic text can be used one of two ways in a dialog or modeless UI: either as a dynamic label or as dynamic content.

 Dynamic label: a common use of dynamic text is in descriptive panels that offer more information for the
selected item, such as in a dialog which contains a list of elements and properties for those elements displayed
in a grid to the right. The label for the property grid may be dynamic so that when an item is selected on the
left, the grid to the right shows information for that specific item.
 Dynamic text: can be useful in instances where you need to display specific information and not general
information in this way, but care should be taken to not overuse.

If you want users to have the ability to copy the info, dynamic text should be in a read-only text field.

Buttons and hyperlinks

Buttons and link controls (hyperlinks) should follow basic Windows Desktop guidance on hyperlinks for usage,
wording, sizing, and spacing.

Choosing between buttons and links

Traditionally, buttons have been used for actions and hyperlinks have been reserved for navigation. Buttons may be
used in all cases, but the role of links has been expanded in Visual Studio so that buttons and links are more
interchangeable in some conditions.

When to use command buttons:

 Primary commands
 Displaying windows used to gather input or making choices, even if they are secondary commands
 Destructive or irreversible actions
pg. 47
C# ( Sharp ) Complete Notes

 Commitment buttons within wizards and page flows

Avoid command buttons in tool windows, or if you need more than two words for the label. Links can have longer
labels.

When to use links:

 Navigation to another window, document, or web page


 Situations that require a longer label or short sentence to describe the intent of the action
 Tight spaces where a button would overwhelm the UI, provided that the action is not destructive or irreversible
 De-emphasizing secondary commands in situations where there are many commands

Examples

Command links used in the InfoBar following a status message

Links used in the CodeLens popup

pg. 48
C# ( Sharp ) Complete Notes

Links used for secondary commands where buttons would attract too much attention

Common buttons

Text

Follow the writing guidelines in UI text and terminology.

Visual style

Standard (unthemed)

Most buttons in Visual Studio will appear in utility dialogs and should not be styled. They should reflect the standard
appearance of buttons as dictated by the operating system.

Themed

In some instances, buttons may be used within styled UI and these buttons must be styled appropriately.
See Dialogs for information on themed controls.

Special buttons

Browse... buttons

[Browse...] buttons are used in grids, dialogs, and tool windows and other modeless UI elements. They display a
picker that assists the user in filling a value into a control. There are two variations of this button, long and short.

pg. 49
C# ( Sharp ) Complete Notes

The long [Browse...] button

The ellipsis-only short [...] button

When to use the ellipsis-only short button:

 If there is more than one long [Browse...] button in a dialog, like when several fields allow for browsing. Use the
short [...] button for each to avoid the confusing access keys created by this situation
(&Browse and B&rowse in the same dialog).
 In a tight dialog, or when there is no reasonable place to put the long button.
 If the button will appear in a grid control.

Guidelines for using the button:

 Don't use an access key. To access it using the keyboard, the user must tab from the adjacent control. Ensure
that the tab order is such that any browse button falls immediately after the field that it will fill. Never use an
underscore below the first period.
 Set the Microsoft Active Accessibility (MSAA) Name property to Browse... (including the ellipsis) so that screen
readers will read it as "Browse" and not "dot-dot-dot" or "period-period-period." For managed controls, this
means setting the AccessibleName property.
 Never use an ellipsis [...] button for anything except a browse action. For example, if you need a [New...] button
but don't have enough room for the text, then the dialog needs to be redesigned.

Sizing and spacing

Sizing [Browse...] buttons

Spacing [Browse...] buttons


pg. 50
C# ( Sharp ) Complete Notes

Graphical buttons

Some buttons should always use a graphical image and never include text to conserve space and avoid localization
problems. These are often used in field pickers and other sortable lists.
Note

Users have to tab to these buttons (there are no access keys), so place them in a sensible order. Map
the name property of the button to the action that it takes so that screen readers correctly interpret the button action.
Expand table
Function Button

Add

Remove

Add All

Remove All

Move Up

Move Down

Delete

Sizing and spacing

Sizing for graphical buttons is the same as for the short version of the [Browse...] button (26x23 pixels):

Appearance of a graphical image on button, with and without transparent color showing

Hyperlinks

Hyperlinks are well suited to navigation-based actions, like opening a Help topic, modal dialog, or wizard. If a
hyperlink is used for a command, it should always display a visible and noticeable change to the UI. In general, actions
that commit to an action (like Save, Cancel, and Delete) are better communicated using a button.

Writing style

Follow the Windows Desktop guidance for user interface text. Don't use "Learn more about," "Tell me more about," or
"Get help with this" phrasing. Instead, phrase Help link text in terms of the primary question answered by the Help
content. For example, "How do I add a server to the Server Explorer?"

pg. 51
C# ( Sharp ) Complete Notes

Visual style

 Hyperlinks should always use The VSColor Service. If a hyperlink is not styled correctly, it flashes red when active
or shows a different color after being visited.
 Don't include underlines at the control resting state unless the link is a sentence fragment within a full sentence,
like in a watermark.
 Underlines shouldn't appear on hover. Instead, the feedback to the user that the link is active is a slight color
change and the appropriate link cursor.

Tree views

Tree views provide a way to organize complex lists into parent-child groups. A user can expand or collapse parent
groups to reveal or hide underlying child items. Each item within a tree view can be selected to provide further action.

Tree view visual style

Expanders

Tree view controls should conform to the expander design used by Windows and Visual Studio. Each node uses an
expander control to reveal or hide underlying items. Using an expander control provides consistency for users who
might encounter different tree views within Windows and Visual Studio.

Correct: proper style of tree view node using an expander control

Incorrect: improper style of tree view node

Selection

When a node is selected within the tree view, the highlight should expand to the full width of the tree view control.
This helps users clearly identify which item they have selected. Selection colors should reflect the current Visual Studio
theme.

Correct: highlight of the selected node fits the entire width of the tree view control.

pg. 52
C# ( Sharp ) Complete Notes

Incorrect: highlight of the selected node doesn't fit the entire width of the tree view control.

Icons

Icons should only be used in tree view controls if they assist in visually identifying differences between items. In
general, icons should be used only in heterogeneous lists in which the Icons carry information to differentiate the
types of elements. In a homogeneous list using icons can frequently be seen as noise and should be avoided. In that
case the group icon (parent) can convey the type of items within it. The exception to this rule would be if the icon is
dynamic and is used to indicate state.

Scroll bars

Scroll bars should always be hidden if the content fits within the tree view control. It is acceptable for scrollbars to be
hidden, or semi-transparent in a scrollable window and appear when the window containing the tree view has focus, or
upon hover of the tree view itself.

Both vertical and horizontal scroll bars are displayed because the contents have exceeded the limits of the tree view
control.

Tree view interactions

Context menus

A tree view node can reveal submenu options in a context menu. Typically, this occurs when a user has right-clicked an
item or pressed the Menu key on a Windows keyboard with the item selected. It's important that the node gains focus
and is selected. This helps the user identify which item the submenu belongs to.

The item that has generate the context menu gains focus to notify the user which item has been selected.

Keyboard

The tree view should provide the ability to select items and expand/collapse nodes using the keyboard. This ensures
that navigation meets our accessibility requirements.

Tree view control

Visual Studio tree controls should follow common keyboard navigation:


pg. 53
C# ( Sharp ) Complete Notes

 Up Arrow: Select items by moving up the tree


 Down Arrow: Select items by moving down the tree
 Right Arrow: Expand a node in the tree
 Left Arrow: Collapse a node in the tree
 Enter key: Initiate, load, execute selected item

Trid (tree view and grid view)

A trid control is a complex control that contains a tree view within a grid. Expanding, collapsing, and navigating the
tree should respect the same keyboard commands as a tree view, with the following additions:

 Right Arrow: Expand a node. After the node is expanded, it should continue navigating to the nearest column
on the right. Navigation should stop at the end of the row.
 Tab: Navigates to the nearest cell on the right. At the end of the row, navigation continues to the next row.
 Shift + Tab: Navigates to the nearest cell on the left. At the beginning of the row, navigation continues to the
rightmost cell in the previous row.

Dynamic Link Library in C#


A dynamic-link library (DLL) is a module that contains functions and data that can be used by another module
(application or DLL). A DLL can define two kinds of functions: exported and internal. The exported functions are
intended to be called by other modules, as well as from within the DLL where they are defined.

Internal functions are typically intended to be called only from within the DLL where they are defined. Although a DLL
can export data, its data is generally used only by its functions. However, there is nothing to prevent another module
from reading or writing that address.

DLLs provide a way to modularize applications so that their functionality can be updated and reused more easily. DLLs
also help reduce memory overhead when several applications use the same functionality at the same time, because
although each application receives its own copy of the DLL data, the applications share the DLL code.
Threads in C#
Multi-threading is the most useful feature of C# which allows concurrent programming of two or more parts of the
program for maximizing the utilization of the CPU. Each part of a program is called Thread. So, in other words,
threads are lightweight processes within a process.

Synchronization in C#
Ensures that only one thread is accessing the shared resource at any given point in time, preventing other threads
from doing the same at the same time. Thread Synchronization in C# is a mechanism that is used to restrict multiple
threads from accessing a shared resource at the same time.
Network programming
is the act of using computer code to write programs or processes that can communicate with other programs or
processes across a network. Programmers use various programming languages, code libraries, and protocols to do
the work.

The .NET framework provides two namespaces, System.Net and System.Net.Sockets for network programming. The
classes and methods of these namespaces help us to write programs, which can communicate across the network.

pg. 54
C# ( Sharp ) Complete Notes

The communication can be either connection-oriented or connectionless. They can also be either stream-oriented or
data-gram-based. The most widely used protocol TCP is used for stream-based communication and UDP is used for
data-grams-based applications.
DNS class
The System.net namespace provides this class, which can be used to create and send queries to obtain information
about the host server from the Internet Domain Name Service (DNS). Remember that in order to access DNS, the
machine executing the query must be connected to a network. If the query is executed on a machine, that does not
have access to a domain name server, a System.Net.SocketException is thrown. All the members of this class are
static in nature. The important methods of this class are given below.
public static IPHostEntry GetHostByAddress(string address)
C#
Copy
Where address should be in a dotted-quad format like "202.87.40.193". This method returns an IPHostEntry instance
containing the host information. If the DNS server is not available, the method returns a SocketException.
public static string GetHostName()
C#
Copy
This method returns the DNS hostname of the local machine.
In my machine Dns.GetHostName() returns Rajesh which is the DNS name of my machine.
public static IPHostEntry Resolve(string hostname)
C#
Copy
This method resolves a DNS hostname or IP address to an IPHostEntry instance. The hostname should be in a
dotted-quad format like 127.0.01 or www.microsoft.com.
IPHostEntry class
This is a container class for Internet host address information. This class makes no thread safety guarantees. The
following are the important members of this class.
AddressList property
Gives an IPAddress array containing IP addresses that resolve to the hostname.
Aliases property
Gives a string array containing a DNS name that resolves to the IP addresses in the AddressList property.

Assembly in C#
private assembly deployment
A private assembly is an assembly that is deployed with an application and is available for the exclusive use of that
application.

Introduction:

Assembly is an important concept in C#. It is a collection of code files that are compiled into an executable or a Dynamic
Link Library (DLL). Depending on their location and intended use, assemblies can be divided into many categories. We
will examine the various assembly types in C# in this article.
Private Assemblies:

An Assembly that is solely used by one application is referred to as a Private Assembly. It is typically found in the directory
for the application or a subdirectory of the directory for the programme. Private Assemblies are not intended to be
shared with other applications. They are used to store application-specific code and resources.

Private Assemblies are created when an application is compiled. When an application is compiled, all the code files and
resources that are used by the application are compiled into a single assembly.The application's directory or a
subdirectory of the application's directory will thereafter contain this assembly.

Private Assemblies are simple to deploy and use. They don't need any extra installation or setting. They are automatically
loaded by the .NET runtime when the application starts.

pg. 55
C# ( Sharp ) Complete Notes

Shared Assemblies:

An assembly that is used by several programmes is referred to as a shared assembly. It is typically found in the Global
Assembly Cache (GAC) or a common directory. Multiple applications are supposed to share a shared assembly. They
are used to store resources and code that are shared by various applications.

Shared Assemblies are created using the strong name tool (sn.exe). A digital signature for the assembly is applied using
the strong name tool. The digital signature guarantees that the assembly is genuine and unaltered.

The Global Assembly Cache (GAC) houses shared assemblies. Shared assemblies are kept in the GAC, which serves as
a central repository. The GAC location is in the Windows directory (C:\Windows\assembly). Shared assemblies are
registered with the GAC using the gacutil.exe tool.

Shared assemblies require special configuration and installation. They cannot be simply copied to the application's
directory. They need to be registered with the GAC using the gacutil.exe tool.
Satellite Assemblies:

An assembly used to store regional resources is referred to as a Satellite Assembly. It is typically found in a subdirectory
of the directory for the application or a subdirectory of the directory for the Shared Assembly. Localized resources like
strings, pictures, and audio files are kept in satellite assemblies.

Satellite Assemblies are created using the resgen.exe tool. The resgen.exe tool is used to create a resource
file (.resx) from a text file. The resource file is then compiled into a satellite assembly using the al.exe tool.
ADVERTISEMENT

Satellite Assemblies are named using a specific naming convention. The naming convention for satellite assemblies is as
follows:
1. <AssemblyName>.resources.dll

The <AssemblyName> part of the name is the name of the main assembly that the satellite assembly is associated
with. The.NET runtime automatically loads satellite assemblies when the application first launches. The .NET runtime
automatically selects the appropriate satellite assembly based on the user's culture settings.
Dynamic Link Libraries (DLLs):

A Dynamic Link Library (DLL) is a type of assembly that contains code that can be used by multiple applications. Similar
to shared assemblies, DLLs are created with the intention of being used by numerous applications. DLLs, however, differ
from shared assemblies in that they do not have a distinctive name.

DLLs are kept in the directory of the application or a subdirectory of the directory of the application. They can be used
by multiple applications by simply copying the DLL to the application's directory.

DLLs are created using the same tools that are used to create shared assemblies. However, DLLs do not require a strong
name. They can be signed with a digital signature, but this is optional.
Configuration in C#
In C#, appsettings. json is a configuration file used to store application settings in a structured format. It is commonly
used in ASP.NET Core applications, but it can also be utilized in other types of C# application

Configuration file in C#
A configuration file (web. config) is used to manage various settings that define a website. The settings are stored in
XML files that are separate from your application code. In this way you can configure settings independently from your
code.

pg. 56
C# ( Sharp ) Complete Notes

Access ASP.NET Configuration Settings Programmatically

You can access run-time configuration settings from within an ASP.NET application or a .NET client application. Each
configuration section has its own object type, which in the case of C# requires a cast when calling the methods of
the WebConfigurationManager class. For more information about the object type that is associated with a
configuration section, see the section handler in the Element Information table in the reference topics under ASP.NET
Configuration Settings.

The code example in this topic uses the non-static method of obtaining configuration data. This allows you to obtain
configuration information from any application. If you are going to obtain configuration information from the
application in which your code resides, use the static GetSection methods, which process faster. For more information,
see the Working with Local and Remote Configuration Settings section in ASP.NET Configuration API Overview.

Software Development Kit (SDK)

A software development kit (SDK) is a set of software tools and programs provided by hardware and software vendors
that developers can use to build applications for specific platforms. SDKs help developers easily integrate their apps
with a vendor's services.
SDKs include documentation, application programming interfaces (APIs), code samples, libraries and processes, as
well as guides that developers can use and integrate into their apps. Developers can use SDKs to build and maintain
applications without having to write everything from scratch.
More specifically, SDKs include the following components:
 Libraries are a collection of reusable and packaged pieces of code that perform specific functions.
 APIs are predefined pieces of code that let developers perform common programming tasks on the platform.
 Integrated development environments (IDEs) are visual editors that help with the design and layout of
graphical elements, such as text boxes and buttons. These are common in mobile software app development
toolkits. For instance, Apple's IDE, Xcode, contains a suite of software development tools to help developers build
software for macOS, iOS, iPadOS, watchOS and tvOS. There are numerous IDE options for Android.
 Testing tools and compilers include debugging tools to help developers identify coding errors at various stages
of application development.
 Documentation encompasses the instructions and tutorials vendors provide to help developers as they go
through the development stages.

Benefits of SDKs
Different types of SDKs can be used for a variety of programming languages and mobile applications. By assembling
the needed set of tools in one location, SDKs simplify standard processes and add more functionality to applications.
The following are the key benefits of using SDKs:
 Time saving. SDKs let developers easily and quickly build the standard components of their apps and add
functionality to them. SDKs are usually all-in-one products and don't need to be integrated with other components,
which can slow down the development process.
 Easier integration. Developers use SDKs for simple functions, such as logging in, location services and mobile
payments. However, some SDKs help developers build more complex app features, such as augmented
reality and virtual reality, and add new features. SDKs reduce the complexity of integrations by simplifying
standard processes, such as creating authorization signatures and interpreting SMS messages in native
languages or platforms.

Metadata
Metadata is binary information describing your program that is stored either in a common language runtime portable
executable (PE) file or in memory. When you compile your code into a PE file, metadata is inserted into one portion of
the file, and your code is converted to Microsoft intermediate language (MSIL) and inserted into another portion of
the file. Every type and member that is defined and referenced in a module or assembly is described within metadata.
When code is executed, the runtime loads metadata into memory and references it to discover information about your
code's classes, members, inheritance, and so on.
Metadata describes every type and member defined in your code in a language-neutral manner. Metadata stores the
following information:
 Description of the assembly.

pg. 57
C# ( Sharp ) Complete Notes

o Identity (name, version, culture, public key).


o The types that are exported.
o Other assemblies that this assembly depends on.
o Security permissions needed to run.
 Description of types.
o Name, visibility, base class, and interfaces implemented.
o Members (methods, fields, properties, events, nested types).
 Attributes.
o Additional descriptive elements that modify types and members.
Benefits of Metadata
Metadata is the key to a simpler programming model, and eliminates the need for Interface Definition Language (IDL)
files, header files, or any external method of component reference. Metadata enables .NET languages to describe
themselves automatically in a language-neutral manner, unseen by both the developer and the user. Additionally,
metadata is extensible through the use of attributes. Metadata provides the following major benefits:
 Self-describing files.
Common language runtime modules and assemblies are self-describing. A module's metadata contains
everything needed to interact with another module. Metadata automatically provides the functionality of IDL in
COM, so you can use one file for both definition and implementation. Runtime modules and assemblies do not
even require registration with the operating system. As a result, the descriptions used by the runtime always
reflect the actual code in your compiled file, which increases application reliability.
 Language interoperability and easier component-based design.
Metadata provides all the information required about compiled code for you to inherit a class from a PE file
written in a different language. You can create an instance of any class written in any managed language (any
language that targets the common language runtime) without worrying about explicit marshalling or using
custom interoperability code.
 Attributes.
.NET lets you declare specific kinds of metadata, called attributes, in your compiled file. Attributes can be found
throughout .NET and are used to control in more detail how your program behaves at run time. Additionally,
you can emit your own custom metadata into .NET files through user-defined custom attributes. For more
information, see Attributes.
Metadata and the PE File Structure
Metadata is stored in one section of a .NET portable executable (PE) file, while Microsoft intermediate language (MSIL)
is stored in another section of the PE file. The metadata portion of the file contains a series of table and heap data
structures. The MSIL portion contains MSIL and metadata tokens that reference the metadata portion of the PE file.
You might encounter metadata tokens when you use tools such as the MSIL Disassembler (Ildasm.exe) to view your
code's MSIL, for example.
Metadata Tables and Heaps
Each metadata table holds information about the elements of your program. For example, one metadata table
describes the classes in your code, another table describes the fields, and so on. If you have ten classes in your code,
the class table will have tens rows, one for each class. Metadata tables reference other tables and heaps. For example,
the metadata table for classes references the table for methods.

Reflection in C#
Reflection objects are used for obtaining type information at runtime. The classes that give access to the metadata of
a running program are in the System.Reflection namespace.

The System.Reflection namespace contains classes that allow you to obtain information about the application and to
dynamically add types, values, and objects to the application.

Applications of Reflection
Reflection has the following applications −
 It allows view attribute information at runtime.
 It allows examining various types in an assembly and instantiate these types.
 It allows late binding to methods and properties
 It allows creating new types at runtime and then performs some tasks using those types.

pg. 58
C# ( Sharp ) Complete Notes

Early Binding

A binding is called an early binding, compiler time binding or static type binding when the target method is found
during compile time (the code that will call the method is also created during compile time). If the required method
doesn’t exist, an error is issued during compilation.

Whether there is an extra step to find the method during call time is irrelevant. That means, the binding is still
considered early independently of if the method is virtual or not.

For example, the next code block uses early binding to call the RandomMethod method of the
object EarlyBindingSample, and then the method NotExistingMethod that doesn’t exist. Since the second method
doesn’t exists, the compiler throws an error:

Late Binding

Late binding or runtime binding in C# is achieved with reflection. Late bound means the target method is looked up at
run time. Often the textual name of the method is used to look it up. If the method isn’t there, the program will crash
or go into some exception handling scheme during run time.

For example, the code bellow uses reflection to locate and execute two methods, one existing and one not. Since the
object returned by the activator is converted to ILateBoundSample, the compiler knows that the
method NotExistingMethod doesn’t exist, so this is causing a compiler error. On the other hand, using the same
interface the compiler assumes that a method named RandomMethod exists in the load type and it compiles properly.
This assumption is usually correct, and the approach saves us from many awkward runtime late binding errors, but
there is no Holy Grail – we can never be sure the implementation of the method RandomMethod actually exists in the
loaded type

Directory in C#
The Directory class in C# and. NET provides functionality to work with folders. This article covers how to read a
folder's properties, get the size and number of files of a folder, create a folder, create a subfolder, iterate through all
files in a folder, move a folder, and delete a folder.

C# Files

Working With Files


The File class from the System.IO namespace, allows us to work with files:
Example
using System.IO; // include the System.IO namespace

File.SomeFileMethod(); // use the file class with methods


The File class has many useful methods for creating and getting information about files. For example:
Method Description

AppendText() Appends text at the end of an existing file

Copy() Copies a file

Create() Creates or overwrites a file

Delete() Deletes a file

Exists() Tests whether the file exists

ReadAllText() Reads the contents of a file

pg. 59
C# ( Sharp ) Complete Notes

Replace() Replaces the contents of a file with the contents of another file

WriteAllText() Creates a new file and writes the contents to it. If the file already exists, it will be overwritten.

Write To a File and Read It


In the following example, we use the WriteAllText() method to create a file named "filename.txt" and
write some content to it. Then we use the ReadAllText() method to read the contents of the file:
C# Serialization
In C#, serialization is the process of converting object into byte stream so that it can be saved to memory, file or
database. The reverse process of serialization is called deserialization.
Serialization is internally used in remote applications.

C# SerializableAttribute
To serialize the object, you need to apply SerializableAttribute attribute to the type. If you don't
apply SerializableAttribute attribute to the type, SerializationException exception is thrown at runtime.
C# Serialization example
Let's see the simple example of serialization in C# where we are serializing the object of Student class. Here, we are
going to use BinaryFormatter.Serialize(stream, reference) method to serialize the object.

Memory Management
Memory management is the process of allocating and de-allocating memory resources during a program’s execution to
ensure efficient utilization of available memory. It plays a critical role in preventing memory-related issues like memory
leaks, buffer overflows, and access violations.

In managed programming languages like C#, memory management is handled by the runtime environment, relieving
developers of many low-level memory management tasks. Common Language Runtime (CLR) is responsible for
managing memory, and it employs a sophisticated garbage collector to automatically release memory that is no longer
in use.

Garbage Collector
The garbage collector (GC) serves as an automatic memory manager. The garbage collector manages the allocation
and release of memory for an application. Therefore, developers working with managed code don't have to write code
to perform memory management tasks. Automatic memory management can eliminate common problems such as
forgetting to free an object and causing a memory leak or attempting to access freed memory for an object that's
already been freed.
This article describes the core concepts of garbage collection.
Benefits
The garbage collector provides the following benefits:
 Frees developers from having to manually release memory.
 Allocates objects on the managed heap efficiently.
 Reclaims objects that are no longer being used, clears their memory, and keeps the memory available for future
allocations. Managed objects automatically get clean content to start with, so their constructors don't have to
initialize every data field.
 Provides memory safety by making sure that an object can't use for itself the memory allocated for another
object.

Asynchronous Delegates

pg. 60
C# ( Sharp ) Complete Notes

Delegates are also used in threading specially for the Callback operation. It enables to call a synchronous method in
an asynchronous manner. It is basically used in cases like to report information back after the completion of operation,
a thread needs a pointer to be able to execute the Callback, etc.

Application Domain
Application domains provide an isolation boundary for security, reliability, and versioning, and for unloading
assemblies. Application domains are typically created by runtime hosts, which are responsible for bootstrapping the
common language runtime before an application is run.
The benefits of isolating applications
Historically, process boundaries have been used to isolate applications running on the same computer. Each
application is loaded into a separate process, which isolates the application from other applications running on the
same computer.
The applications are isolated because memory addresses are process-relative; a memory pointer passed from one
process to another cannot be used in any meaningful way in the target process. In addition, you cannot make direct
calls between two processes. Instead, you must use proxies, which provide a level of indirection.
Managed code must be passed through a verification process before it can be run (unless the administrator has
granted permission to skip the verification). The verification process determines whether the code can attempt to
access invalid memory addresses or perform some other action that could cause the process in which it is running to
fail to operate properly. Code that passes the verification test is said to be type-safe. The ability to verify code as type-
safe enables the common language runtime to provide as great a level of isolation as the process boundary, at a much
lower performance cost.
Application domains provide a more secure and versatile unit of processing that the common language runtime can
use to provide isolation between applications. You can run several application domains in a single process with the
same level of isolation that would exist in separate processes, but without incurring the additional overhead of making
cross-process calls or switching between processes. The ability to run multiple applications within a single process
dramatically increases server scalability.
Isolating applications is also important for application security. For example, you can run controls from several Web
applications in a single browser process in such a way that the controls cannot access each other's data and resources.
The isolation provided by application domains has the following benefits:
 Faults in one application cannot affect other applications. Because type-safe code cannot cause memory faults,
using application domains ensures that code running in one domain cannot affect other applications in the
process.
 Individual applications can be stopped without stopping the entire process. Using application domains enables
you to unload the code running in a single application.
 Code running in one application cannot directly access code or resources from another application. The
common language runtime enforces this isolation by preventing direct calls between objects in different
application domains. Objects that pass between domains are either copied or accessed by proxy. If the object is
copied, the call to the object is local. That is, both the caller and the object being referenced are in the same
application domain. Application domains and assemblies
The runtime host determines whether to load assemblies as domain-neutral when it loads the runtime into a process.
For managed applications, apply the LoaderOptimizationAttribute attribute to the entry-point method for the process,
and specify a value from the associated LoaderOptimization enumeration. For unmanaged applications that host the
common language runtime, specify the appropriate flag when you call the CorBindToRuntimeEx Function method.
There are three options for loading domain-neutral assemblies:
 LoaderOptimization.SingleDomain loads no assemblies as domain-neutral, except Mscorlib, which is always
loaded domain-neutral. This setting is called single domain because it is commonly used when the host is
running only a single application in the process.
A domain-neutral assembly can be JIT-compiled more than once. For example, when the security grant sets of two
application domains are different, they cannot share the same JIT-compiled code. However, each copy of the JIT-
compiled assembly can be shared with other application domains that have the same grant set.
When you decide whether to load assemblies as domain-neutral, you must make a tradeoff between reducing memory
use and other performance factors.

pg. 61
C# ( Sharp ) Complete Notes

 Access to static data and methods is slower for domain-neutral assemblies because of the need to isolate
assemblies. Each application domain that accesses the assembly must have a separate copy of the static data, to
prevent references to objects in static fields from crossing domain boundaries. As a result, the runtime contains
additional logic to direct a caller to the appropriate copy of the static data or method. This extra logic slows
down the call.
 All the dependencies of an assembly must be located and loaded when the assembly is loaded domain-neutral,
because a dependency that cannot be loaded domain-neutral prevents the assembly from being loaded
domain-neutral.

Application domains and threads


An application domain forms an isolation boundary for security, versioning, reliability, and unloading of managed
code. A thread is the operating system construct used by the common language runtime to execute code. At run time,
all managed code is loaded into an application domain and is run by one or more managed threads.
There is not a one-to-one correlation between application domains and threads. Several threads can execute in a
single application domain at any given time, and a particular thread is not confined to a single application domain.
That is, threads are free to cross application domain boundaries; a new thread is not created for each application
domain.
Programming with application domains
Application domains are usually created and manipulated programmatically by runtime hosts. However, sometimes an
application program might also want to work with application domains. For example, an application program could
load an application component into a domain to be able to unload the domain (and the component) without having
to stop the entire application.
The AppDomain is the programmatic interface to application domains. This class includes methods to create and
unload domains, to create instances of types in domains, and to register for various notifications such as application
domain unloading. The following table lists commonly used AppDomain methods.
Expand table
AppDomain Method Description
CreateDomain Creates a new application domain. It is recommended that you use an overload of this
method that specifies an AppDomainSetup object. This is the preferred way to set the
properties of a new domain, such as the application base, or root directory for the
application; the location of the configuration file for the domain; and the search path that
the common language runtime is to use to load assemblies into the domain.
ExecuteAssembly and ExecuteAs Executes an assembly in the application domain. This is an instance method, so it can be
semblyByName used to execute code in another application domain to which you have a reference.
CreateInstanceAndUnwrap Creates an instance of a specified type in the application domain, and returns a proxy. Use
this method to avoid loading the assembly containing the created type into the calling
assembly.
Unload Performs a graceful shutdown of the domain. The application domain is not unloaded until
all threads running in the domain have either stopped or are no longer in the domain.

Marshal by Value and Reference in visual c#


In C#, "marshal by value" and "marshal by reference" refer to different ways of passing objects between application
domains or across processes.

Marshal by Value: When you marshal an object by value, a copy of the object is passed to the target location. Any
changes made to the copy do not affect the original object. In C#, you can use the Serializable attribute to mark a
class as serializable, allowing it to be marshaled by value.

Marshal by Reference: When you marshal an object by reference, you pass a reference to the object, rather than a
copy of the object itself. This means that changes made to the object at the target location affect the original object. In
C#, you can use remoting or other inter-process communication mechanisms to achieve marshal by reference
pg. 62
C# ( Sharp ) Complete Notes

Authentication & Authorization:

In Visual C# (or C# in general), authorization and authentication are typically implemented using various .NET
frameworks and libraries. Here's a basic overview of each:

1. Authentication: Authentication is the process of verifying the identity of a user. In C#, you can implement
authentication using ASP.NET Identity, which provides features for managing user accounts, including password
hashing, two-factor authentication, and external authentication providers (such as Google, Facebook, etc.).

2. Authorization: Authorization is the process of determining whether an authenticated user has the necessary
permissions to access a resource. In C#, you can use ASP.NET Core's authorization middleware to implement role-
based or policy-based authorization.
Configuring security

Configuring security in Visual C# typically involves securing your application at various levels, including the application
level, web server level, and network level. Here's a general overview of how you can configure security in a Visual C#
application:

1. Code Access Security (CAS): Code Access Security allows you to control what your code is allowed to do, based on
where it comes from and who wrote it. However, CAS has been deprecated since .NET Framework 4 and is no longer
recommended for new development.
2. Code Group Security: Code groups are used in CAS to group assemblies with similar permissions requirements. Each
code group is associated with a permission set that determines the permissions granted to assemblies in that code
group.

Principles and identities in Visual C#

1. dentity: An identity represents the user or entity (such as a service or application) that is trying to access a resource. In
.NET, the System.Security.Principal.IIdentity interface represents an identity. An identity typically contains
information such as the name of the user and any roles or claims associated with the user.

2. Principal: A principal represents the security context under which code is running, including the identity of the user
and any roles or claims associated with the user. In .NET, the System.Security.Principal.IPrincipal
interface represents a principal. The Thread.CurrentPrincipal property is commonly used to get or set the
current principal for the current thread.

Principals and identities are fundamental to implementing authentication and authorization in .NET applications,
allowing you to control access to resources based on the identity and roles of the user.
Data Reader in Visual C#
In Visual C#, a DataReader is used to efficiently read a forward-only stream of rows from a data source, such as a
database (e.g., SQL Server, MySQL). It's part of the ADO.NET framework and is particularly useful when you need to
read large sets of data quickly and efficiently.

Using Data Sets in Visual C#


In Visual C#, a DataSet is an in-memory cache of data retrieved from a data source, typically a database. It's part of
the ADO.NET framework and provides a disconnected representation of the data, meaning it does not need to
maintain an open connection to the database. DataSets can contain one or more DataTable objects, which represent
a single table of data.

Here's a basic example of using a DataSet to retrieve and manipulate data from a SQL Server database:

In this example, replace YourServer, YourDatabase, YourTable, and TableName with your actual server,
database, and table names. The SqlDataAdapter is used to fill the DataSet with data from the database. You can
then access the data in the DataSet through its Tables collection, which contains DataTable objects. Each
DataTable represents a table of data and can be iterated over to access its rows and columns.

pg. 63
C# ( Sharp ) Complete Notes

Intracting with XML in Visual C#

Interacting with XML in Visual C# involves reading, writing, and manipulating XML data using the classes provided in
the .NET Framework's System.Xml namespace. XML (eXtensible Markup Language) is a widely used format for
storing and exchanging data in a structured way. Here's a brief overview of how you can work with XML in Visual C#
Tracing to Event Logs
Using tracing within an application allows its activities to be logged and reviewed later to assist with identifying and
resolving bugs. Messages can be sent to various locations, including Windows event logs that can be examined using
the Event Viewer.

EventLogTraceListener
When you are developing applications it is useful to include logging functionality. If you encounter bugs, or when test
users report issues, the logs can be reviewed and may help you to track down those problems. A simple way of
providing logging is via the Debug and Trace classes. These classes allow you to output messages to trace listeners,
which control how those messages are outputted. For example, information can easily be sent to the Visual Studio
output window or to a text file.

Using Boolean and Trace Switch classes

The Boolean Switch and Trace Switch classes are used for controlling the tracing output of your application. They
allow you to dynamically enable or disable tracing based on the value of a switch. Here's how you can use them:

Boolean Switch: This switch is either on or off (true or false). It's useful when you only need to enable or disable
tracing without different levels of verbosity.

TraceSwitch: This switch allows you to specify different levels of tracing (e.g., Off, Error, Warning, Info, Verbose).
You can set the Level property to control the verbosity of the tracing output

Print Debugging Information with the debug class

In C#, you can use the Debug class from the System.Diagnostics namespace to print debugging information. The
Debug class provides methods for writing debug messages to the output window in development environments like
Visual Studio. Here's a basic example:

In this example, Debug.WriteLine is used to print debug messages to the output window. You can use string
interpolation ($"") to include variable values in the messages. Debug.Assert can be used to assert a condition and
print a message if the condition is false. When running the application in Visual Studio, you can view the debug output
in the "Output" window (View -> Output)

Instrumentation Release Builds with the Trace Class

Application instrumentation gives you the ability to perform runtime diagnosis of enterprise application state, which is
critical to mission success.

To help with instrumentation and logging, .NET ships with tracing types in the System.Diagnostics namespace. Using
these types, you have the ability to log information to multiple output streams for diagnosis of application runtime
behavior. Information produced by instrumentation and tracing types enable you to examine the runtime state of an
application and fix problems that would be otherwise expensive and painful to solve.

The Trace class allows you to perform logging in a production system, giving you the ability to analyze application
behavior during run time.

Two of the primary types in the System.Diagnostics namespace for application instrumentation are
the Debug and Trace classes. Both classes have the same functionality but different use cases. Use the Debug class
during development and use the Trace class in production applications.

pg. 64
C# ( Sharp ) Complete Notes

The types for debugging and tracing, which come with the .NET Framework library, are convenient because they
provide reuse and extendable functionality. You don't have to create your own logging library and you can build
custom instrumentation types.

When tracing, you can control output with switches. A BooleanSwitch turns tracing on and off. TraceSwitch lets you
trace at different levels. Alternatively, you can create a custom switch to define identifiers, granularity, and logic that
meets the requirements of a given application.
Trace output is sent to another type called a TraceListener. .NET ships with trace listeners for writing to the console,
event log, or text files. You can also define your own trace listener for output to the stream of your choice.
Instrumentation is a critical component of enterprise application development, enabling you to build maintainable,
reliable, and robust systems. Through Debug and Trace classes, switches, and trace listeners, you have the ability to
instrument your application in an easy and flexible manner.
Configuration

The Debug and Trace classes have the same functionality, but Microsoft designed them for different purposes. You
use the Debug class for development purposes and it relies on DEBUG being defined. Use the Trace class for
production purposes. It relies on TRACE being defined.
By default, Visual Studio .NET (VS.NET) defines both DEBUG and TRACE for Debug (development) configurations
and only TRACE for Release (production) configurations. To view your project configurations in VS.NET, right-click on
the project, select Properties, select Configuration Properties, select the Build option, and view the Conditional
Compilation Constants property. When compiling C# applications from the command-line, compilation configuration
options are specified with the /define: or /d: option, as follows:
csc.exe /d:TRACE MyApp.cs

Basic Tracing

For this article we'll use the Trace class to show how to use .NET types for instrumentation of production systems.
While I wrote the examples in this article as Console applications for simplicity, you can use this information for
instrumenting any kind of .NET application, including ASP.NET, remoting, Web services, and Windows Forms.
The Trace class has several members that control output, which you can see in Listing 1.
When your tracing needs are simple, that is, you only need to turn tracing on or off, a Boolean switch is a good choice.

The first line in Listing 1 adds a TraceListener to the Listeners collection. TraceListeners are discussed in the
Trace Listeners section of this article. They let you specify where the output of write statements will go.
The WriteLine and Write methods write output with and without a newline, respectively.
The WriteLineIf and WriteIf methods write output if a condition evaluates to true. The category parameter enables
you to prefix the output with a tag string, which is useful for filtering log entries.
Boolean Switches

A BooleanSwitch will allow you to produce trace output only when the switch is true. When all tracing is turned on,
the output can quickly use a lot of resources if saving output to file or some other persistent store. If your application is
small or you don't hold log information longer than immediate diagnosis, a BooleanSwitch will work fine. Listing
2 shows how to use a BooleanSwitch.
The code in Listing 2 is very simple?if boolSwitch.Enabled evaluates to true, then the string parameter to
the WriteLineIf method is sent to output.
Trace Switches

The problem with a BooleanSwitch approach to instrumentation is that it is all-or-nothing. Most of the time, you need
more granularity in your approach. For example, perhaps during normal operations you only want to know about error
conditions. However, to diagnose a problem, you need the ability to trace more information for a short period of time.
The level of information you need at any given time could vary depending on what you need to know. Here you'll find
value using the TraceSwitch.
When your code declares the TraceSwitch variable, it is instantiated with the MyTraceSwitch parameter, which
corresponds to the same entry in the switches element of the configuration file in Listing 5. This configuration file
sets MyTraceSwitch to 4, which turns on tracing for Verbose and every level below it. As implied, the trace level
setting in the configuration file turns on tracing for the level it is set at in addition to all lower levels.
The TraceSwitch class has Boolean properties that correspond to each trace level. Listing 4 demonstrates how to
use the traceSwitch variable as the first parameter to WriteLineIf to determine if a specific trace level is set before
logging output.
Custom Switches
pg. 65
C# ( Sharp ) Complete Notes

Switches that ship with .NET will work fine for most cases. However, there are times when you may want to implement
your own custom switches. Perhaps you want to migrate another system where you have a different logging strategy
that worked and you want to mimic that strategy in .NET. What if the all-inclusive logic of the TraceSwitch didn't quite
meet your needs?
Existing switches don't provide the output control you need? With reusable types in the .NET Framework Class Library
you can create your own custom switch.

I'll demonstrate how to create a custom switch. I designed my example to give you ideas of how you could implement
your own custom switch to achieve the granularity and logic handling appropriate for your needs.

The custom switch in Listing 6, FlagSwitch, creates new switch categories: None, Enter, Exit, Info, and Exception.
As opposed to the TraceSwitch where higher switch levels are all inclusive of lower levels, the FlagSwitch lets you
turn categories on and off at will.
Advertisement

The FlagLevel enum is decorated with the [Flags] attribute, allowing you to use it in bitwise operations. You can
explicitly set each element with a hex value to ensure their values don't overlap.
Notice how my example exposes each switch setting as a property. The get accessors use the SwitchSetting of the
base class, Switch, and use a bit-wise AND operation to check if the bit representing that condition is set.
The Switch class takes care of reading configuration file settings and ensures that the SwitchSetting property is set
accordingly. The implementation also ensures that in all properties, except for None, the None bit is turned off, since
this would represent an illogical condition.
Trace Configuration

The configuration files in previous examples showed how to add a single switch to an application. You can do more
with configuration files including add additional switches and remove switches. The following snippet shows these
additional switch configuration capabilitie

The configuration file adds three switches, which you can use in different parts of an application to give you more
control over where you want to view debug output. The remove element essentially un-defines TraceSwitch2,
making any conditional Trace statements in your code evaluate to false and not print. The remove element provides
a way to turn a switch off, which is an alternative to deleting, commenting, or setting a value to 0 (assuming that 0
represents a condition that prevents trace output) of an existing switch.

Dynamic Switch Settings

Besides using configuration files, you can change switch settings dynamically in code. For example, the following
code modifies the TraceLevel setting to None for a TraceSwitch:

switch1.Level = TraceLevel.Off;

If you needed to dynamically set the switch on a custom switch, you should provide a property that accepts an enum
for the custom switch type. The implementation of that property can get and set base.SwitchSetting appropriately.
The following property implements this for the custom switch described in the Custom Switches section of this article:

This is necessary because the Switch.SwitchSetting property has protected visibility.


Trace Listeners

You use tracing so you can collect run time information from your application to diagnose problems. This means that
there is a location where you can obtain the information, which is where trace listeners come in. A trace listener is a
type that allows you to persist your trace information to a location where it can be stored and analyzed. .NET ships
with three built-in trace listeners: DefaultTraceListener, TextWriterTraceListener, and EventLogTraceListener.

Using DefaultTraceListener

The DefaultTraceListener, as its name implies, is where .NET automatically sends all trace output. The output is sent
to a Win32 API called OutputDebugString. In Visual Studio .NET, the DefaultTraceListener output appears in
the Output window.
You can use trace listeners to control output destination including debug output, console, or the Windows Event Log.
pg. 66
C# ( Sharp ) Complete Notes

You can configure a given application with multiple trace listeners. When this occurs, each write operation will be
routed to every trace listener installed. Additionally, .NET shares all trace listeners with the Debug and Trace classes,
regardless of what switch they are using.
The Listeners property of the Trace class exposes a ListenersCollection type, which implements IList. This means
that if you prefer not to have output sent to the DefaultTraceListener you can use the Remove method as follows:

Using TextWriterTraceListener

A TextWriterTraceListener writes trace output to a file. To use it, instantiate a TextWriterTraceListener class and
add it to the Listeners collection. Listing 7 shows you how to set up a TextWriterTraceListener.
The code in Listing 7 creates a file stream and passes it to the TextWriterTraceListener, which will then write trace
output to the TraceDemo.log file as well as to all the other trace listeners in the Listeners collection.

Using EventLogTraceListener

Another trace listener that ships with .NET is the EventLogTraceListener, which writes to the Windows Event
Log. Listing 8 shows how to use the EventLogTraceListener.
The code in Listing 8 adds an EventLogTraceListener type to the Trace class Listeners collection, along with other
listeners. The algorithm automatically starts the mmc snap-in for the Windows Event Viewer so you can see the new
entry.
Creating a Custom Trace Listener

The trace listeners that ship with .NET are good for most applications. However, you may need to direct trace output
to another destination that the existing trace listeners don't support. For example, suppose you want to send trace
output to a database or maybe output to a special window in your application? Fortunately, you can use types in the
.NET Framework Library to create a custom trace listener.

When existing trace listeners don't meet your needs, you can create your own.

All trace listeners inherit the TraceListener class, an abstract class providing default behavior and virtual methods for
you to override in your own custom trace listener. The TraceListener class has abstract
Write and WriteLine methods that take a single string as a parameter. Listing 9 shows the implementation of the
custom trace listener.
The demo in Listing 9 contains a custom trace listener, WindowTraceListener, which opens a Windows Form and
writes trace output to a text box. The WindowTraceListener class inherits TraceListener. Its implementation is
minimal, overriding only the required Write and WriteLine methods, but Listing 9 demonstrates how easy it is to
create a custom trace listener. You will want to override all of the virtual overloads of the TraceListener class
for Write, WriteLine, Fail, and Assert for a more robust implementation.

pg. 67

You might also like