Backend Development with .NET
Session 03
C# Fundamentals
Types, Control Flow & Arrays
Eng. Seif Mansour  ·  Andalusia Academy
Week 2  ·  2 hours
Session Goals

By the end of this session, you will be able to:

  • Declare variables using the correct data type for a given situation
  • Convert between types safely using built-in methods
  • Control program flow using conditions and loops
  • Declare, initialize, and traverse arrays
Agenda
TimeTopicTypeDuration
0:00Variables & data typesTheory + Demo25 min
0:25Type conversionTheory + Demo15 min
0:40Conditions: if/else & switchTheory + Demo20 min
1:00Break5 min
1:05Loops: for, while, foreachTheory + Demo20 min
1:25ArraysTheory + Demo20 min
1:45ExercisesExercise15 min
Variables &
Data Types
C# is statically typed — every variable has a fixed type set at compile time.
You will learn
  • Value types vs reference types
  • Type inference with var
  • String interpolation & verbatim strings
Value Types

Stored directly on the stack. Each variable holds its own copy of the data.

TypeDescriptionExample
int32-bit integerint age = 25;
long64-bit integerlong pop = 8_000_000_000L;
double64-bit floating pointdouble price = 9.99;
decimal128-bit high-precisiondecimal tax = 0.15m;
booltrue or falsebool isActive = true;
charSingle Unicode characterchar grade = 'A';
Tip
Use decimal for money and financial calculations — double has floating-point rounding errors.
Reference Types & Type Inference

Reference types — stored on the heap; the variable holds a reference, not the value itself.

TypeDescription
stringSequence of characters
objectBase of every .NET type

var — the compiler infers the type. The type is still fixed at compile time.

Remember
var is not dynamic. You cannot change the type after assignment.
// Reference types
string name = "Alice";
object anything = 42;

// Type inference with var
var count = 10;        // int
var price = 9.99m;     // decimal
var label = "Hello";   // string

// This would be a compile error:
// var x = 1;
// x = "hello";  // cannot change type
Strings: Interpolation & Verbatim
// String interpolation — embed expressions with $""
string firstName = "Alice";
int year = 2025;
string message = $"Hello, {firstName}! Born in {year - 25}.";
// → "Hello, Alice! Born in 2000."

// Verbatim string — backslashes are treated literally, no escape needed
string path = @"C:\Users\Alice\Documents\notes.txt";
string multiLine = @"Line one
Line two
Line three";
Note
You can combine both: $@"C:\Users\{userName}\files" gives interpolation inside a verbatim string.
Type Conversion
Moving data between types safely — and knowing when it can go wrong.
You will learn
  • Implicit vs explicit conversion
  • The Convert class
  • Parse and TryParse
Implicit vs Explicit Conversion

Implicit — safe, no data loss. The compiler does it automatically when the destination type can hold all values of the source type.

int x = 100;
long y = x;      // int → long
double d = x;    // int → double

Explicit cast — possible data loss. You must declare it with (type).

double pi = 3.14159;
int truncated = (int)pi;
// truncated = 3 — decimal part lost!
Caution
Casting a long to int will silently overflow if the value is too large. The compiler will not warn you.

Convert class — converts between unrelated types. Throws on failure.

int n = Convert.ToInt32("42");
bool b = Convert.ToBoolean("true");
double d = Convert.ToDouble("3.14");
Parse & TryParse
// Parse — throws FormatException if the string is not a valid number
int a = int.Parse("100");   // fine
int b = int.Parse("abc");   // throws!

// TryParse — returns false instead of throwing; always prefer for user input
string userInput = Console.ReadLine();

if (int.TryParse(userInput, out int result))
{
    Console.WriteLine($"You entered: {result}");
}
else
{
    Console.WriteLine("That is not a valid integer.");
}
Best Practice
Always use TryParse when handling any input you did not create yourself — user input, file reads, API responses.
Conditions
Branching based on values — the foundation of every decision in code.
You will learn
  • if / else if / else
  • Ternary operator ? :
  • switch statement & switch expression
if / else & Ternary Operator

Multi-branch with if

int score = 75;

if (score >= 90)
{
    Console.WriteLine("A");
}
else if (score >= 75)
{
    Console.WriteLine("B");
}
else
{
    Console.WriteLine("C or below");
}

Ternary — single-expression two-branch

// condition ? valueIfTrue : valueIfFalse
string label = score >= 50 ? "Pass" : "Fail";

// Useful for assignments and return values
bool isAdult = age >= 18;
string message = isAdult
    ? "Access granted"
    : "Access denied";
Tip
Keep ternary expressions simple. If the branches are complex, use a full if statement instead.
switch Statement & switch Expression

Classic switch statement

string day = "Saturday";

switch (day)
{
    case "Saturday":
    case "Sunday":
        Console.WriteLine("Weekend");
        break;
    case "Monday":
        Console.WriteLine("Back to work");
        break;
    default:
        Console.WriteLine("Weekday");
        break;
}

switch expression (C# 8+) — returns a value

string type = day switch
{
    "Saturday" or "Sunday" => "Weekend",
    "Monday"               => "Back to work",
    _                      => "Weekday"
};

// Works great for mapping enums too:
string label = status switch
{
    TaskStatus.Pending    => "Not started",
    TaskStatus.Completed  => "Done",
    _                     => "In progress"
};
Common Mistake
Forgetting break in a switch statement causes fall-through to the next case.
Loops
Repeating operations — the engine behind iteration, data processing, and control flow.
You will learn
  • for, while, do-while
  • foreach for collections
  • break and continue
for & while Loops

for — when you know the number of iterations

// init ; condition ; update
for (int i = 0; i < 5; i++)
{
    Console.WriteLine(i);
}
// Prints: 0 1 2 3 4

// Nested — multiplication table
for (int i = 1; i <= 3; i++)
    for (int j = 1; j <= 3; j++)
        Console.WriteLine($"{i}x{j}={i*j}");

while — check condition before each iteration

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

// do-while — body runs at least once
int input;
do
{
    Console.Write("Enter a positive number: ");
    input = int.Parse(Console.ReadLine());
} while (input <= 0);
foreach & Loop Control

foreach — cleanest way to iterate over a collection

string[] names = { "Alice", "Bob", "Carol" };

foreach (string name in names)
{
    Console.WriteLine(name);
}

// Works on any IEnumerable — arrays,
// lists, query results, and more.
Note
Prefer foreach over index-based for whenever you do not need the index.

break and continue

for (int i = 0; i < 10; i++)
{
    if (i == 3) continue;  // skip 3
    if (i == 7) break;     // stop at 7
    Console.WriteLine(i);
}
// Prints: 0 1 2 4 5 6
  • break — exits the loop immediately
  • continue — skips to the next iteration
Arrays
Fixed-size, ordered collections of a single type. The simplest data structure in C#.
You will learn
  • Declaring and initializing arrays
  • Indexing and the Length property
  • Array.Sort, Reverse, IndexOf
Declaring & Using Arrays

Declaration and initialization

// Fixed size, zero-initialized
int[] scores = new int[5];
// → [0, 0, 0, 0, 0]

// Initialize with values
int[] primes = { 2, 3, 5, 7, 11 };

// Equivalent long form
string[] names = new string[] { "Alice", "Bob" };

// Access by index (zero-based)
Console.WriteLine(primes[0]);  // 2
primes[2] = 99;                // replace 5 with 99
Console.WriteLine(primes.Length); // 5

Common operations

int[] numbers = { 5, 2, 8, 1, 9 };

Array.Sort(numbers);
// → [1, 2, 5, 8, 9]

Array.Reverse(numbers);
// → [9, 8, 5, 2, 1]

int pos = Array.IndexOf(numbers, 5);
// → 2  (index of value 5)

// Iterate with foreach
foreach (int n in numbers)
    Console.Write(n + " ");
Common Mistake
Accessing index arr[arr.Length] throws IndexOutOfRangeException. Valid indices are 0 to Length - 1.
Multi-dimensional Arrays
// 2D array — rows × columns
int[,] grid = new int[3, 3];
grid[0, 0] = 1;
grid[1, 2] = 7;

// Initialize inline
int[,] matrix = {
    { 1, 2, 3 },
    { 4, 5, 6 },
    { 7, 8, 9 }
};
Console.WriteLine(matrix[1, 1]);  // 5 (row 1, column 1)

// Iterate with nested loops
for (int row = 0; row < matrix.GetLength(0); row++)
    for (int col = 0; col < matrix.GetLength(1); col++)
        Console.Write(matrix[row, col] + " ");
Common Mistakes to Avoid
Mistake 1 — Float Comparison
Never use == to compare double or float. Use Math.Abs(a - b) < 0.0001 instead — floating-point arithmetic is imprecise.
Mistake 2 — Missing break in switch
Forgetting break causes fall-through: execution continues into the next case block, producing unexpected results.
Mistake 3 — Off-by-One in for loops
Decide once: upper bound is < Length or <= Length - 1. Mixed usage causes skipped or out-of-bounds elements.
Mistake 4 — Array Index Out of Range
Accessing arr[arr.Length] throws at runtime. Arrays are zero-based: valid indices are 0 to arr.Length - 1.
Summary
  • C# is statically typed — every variable has a fixed type set at compile time
  • Value types (int, bool, double) live on the stack; reference types (string, objects) live on the heap
  • Use TryParse — not Parse — whenever the input comes from outside your code
  • switch expressions (C# 8+) are more concise than switch statements and always return a value
  • Prefer foreach over index-based for when you do not need the index
  • Arrays have a fixed size; valid indices run from 0 to Length - 1
What's Next

Session 04 — C# Methods, Strings & Exception Handling

  • Defining and calling methods with various parameter types
  • Method overloading, optional and named parameters
  • String manipulation and StringBuilder
  • Handling null safely — nullable types, ??, ?.
  • Exception handling with try / catch / finally
Before next session
Complete the exercises on the next slide before Session 04.
Assignment

Build a small C# console program that demonstrates your understanding of types, control flow, and arrays.

Acceptance criteria:

  • Accept an integer from the user and print whether it is even or odd — use TryParse to handle invalid input gracefully
  • Print the multiplication table (1 to 10) for the entered number using a for loop
  • Declare an array of 5 integers, fill it with user input, then print the minimum and maximum values without using Array.Sort
  • Use a switch expression to map the maximum value to a label: <10 = "Low", 10–99 = "Medium", ≥100 = "High"
  • All output must be clearly labeled so the user knows what each line means
Bonus
Extend the program to accept a second array of integers and print only the values that appear in both arrays (without using any collection classes — arrays only).
Questions?
Session 03  ·  C# Fundamentals: Types, Control Flow & Arrays