Lecture 1 / 12
Lecture 01 · Fundamentals

Introduction to C# & .NET Setup

Beginner ~75 min No prerequisites

What is C#?

C# (pronounced "C-sharp") is a modern, object-oriented, and type-safe programming language developed by Microsoft. It is designed to be simple, powerful, and versatile. While it shares roots with C and C++, it incorporates modern features that make it more productive and less prone to errors.

C# is the primary language for the .NET ecosystem, meaning it can be used to build almost anything:

  • Enterprise Software: Robust backend systems for banks and corporations.
  • Web Development: Using ASP.NET Core to build high-performance APIs and websites.
  • Game Development: The industry standard for the Unity Engine.
  • Cloud Services: Deep integration with Microsoft Azure for scalable cloud apps.
  • Mobile Apps: Cross-platform development via .NET MAUI.

The .NET Ecosystem: How it Works

To understand C#, you must understand .NET. C# is the language, but .NET is the runtime and library that executes the code.

Professional Insight: The Compilation Process

C# does not compile directly into machine code (binary). Instead, it follows a two-step process:

  1. C# Source Code $\rightarrow$ Compiled into CIL (Common Intermediate Language).
  2. CIL $\rightarrow$ Translated by the CLR (Common Language Runtime) using JIT (Just-In-Time) Compilation into machine code that your specific CPU understands.

This is why C# is cross-platform; the CIL is the same regardless of whether you are on Windows, Linux, or macOS.

Setting Up Your Environment

To start developing, you need two main components: the SDK and an IDE.

1. The .NET SDK (Software Development Kit)

The SDK contains the compilers, libraries, and tools (like the dotnet command) needed to build applications. Download the latest version from dotnet.microsoft.com.

terminal / cmd
dotnet --version
# Expected Output: 8.0.x (or the latest stable version)

2. Choosing Your Editor (IDE)

  • Visual Studio 2022: The "Full Power" IDE. Best for large enterprise projects and Windows desktop apps.
  • VS Code: A lightweight, fast editor. Preferred by many professionals for web development and cross-platform work (requires the "C# Dev Kit" extension).
  • JetBrains Rider: A premium, high-performance cross-platform IDE.

Anatomy of Your First Program

Let's look at a standard C# program and break down exactly what each line is doing.

Program.cs
using System;

class Program
{
    static void Main()
    {
        Console.WriteLine("Hello, World!");
        Console.WriteLine("Welcome to C# Mastery!");
    }
}

Code Breakdown:

  • using System;: This tells the program to use the System namespace, which contains fundamental classes like Console.
  • class Program: C# is an Object-Oriented language. Every piece of code must live inside a class.
  • static void Main(): This is the Entry Point. When you run your app, the .NET runtime looks for this exact method to start execution.
  • Console.WriteLine(): A method used to print text to the terminal/console.

💻 Try It Yourself - Multi-Language Compiler

Practice C# and many other programming languages right here in your browser! Switch between languages, modify the code, and click "Run" to see results instantly.

💡 Practice Tips:

  • Switch to C# in the language selector and try the .NET examples
  • Experiment with C#'s strong typing and object-oriented features
  • Try other languages like Java, TypeScript, or Go to compare syntax
  • Use the "Load Example" button to see C#-specific code samples
  • Use Ctrl+Enter to quickly run your code

Interacting with the User

Professional apps aren't just one-way; they interact with users. We use Console.ReadLine() to capture input.

Program.cs
using System;

class Program
{
    static void Main()
    {
        Console.Write("Enter your name: ");
        string userName = Console.ReadLine();
        Console.WriteLine("Hello, " + userName + "! Welcome to the course.");
    }
}
🎯 Professional Lab 1.1

Objective: Create a "User Profile Generator".

Build a console application that asks the user for the following four pieces of information:

  • Full Name
  • Age
  • Country of Residence
  • Favorite Programming Language

Once the input is collected, the program should print a professional summary: "User Profile: [Name], [Age] years old, from [Country], specializing in [Language]."

Lecture 02 · Fundamentals

Variables & Data Types

Beginner ~90 min Prerequisite: Lecture 1

Understanding Variables

In programming, a variable is a named storage location in the computer's memory. Think of it as a labeled box where you can store a value, and then retrieve or change that value later in your program.

Professional Concept: Strong Typing

C# is a Strongly Typed language. This means that every variable must have a defined type. Once a variable is declared as an integer, you cannot store a string in it. This prevents a huge category of bugs that occur in "loosely typed" languages like JavaScript.

Primitive Data Types

C# provides a variety of built-in types to handle different kinds of data. Choosing the right type is critical for performance and memory efficiency.

Type Storage Size Description Example
int 4 bytes Whole numbers (Integers) int age = 25;
double 8 bytes Decimal numbers (Floating point) double price = 19.99;
decimal 16 bytes High-precision decimals (Financial) decimal tax = 15.50m;
bool 1 byte True or False values bool isComplete = true;
char 2 bytes Single character (Unicode) char grade = 'A';
string Variable Sequence of characters (Text) string name = "Alice";
⚠️ Critical Note: Double vs. Decimal

Never use double or float for financial calculations. They use binary floating-point math which can cause tiny rounding errors (e.g., 0.1 + 0.2 = 0.30000000000000004). Always use decimal for money to ensure absolute precision.

The var Keyword (Implicit Typing)

C# allows you to use the var keyword. This tells the compiler to infer (guess) the type based on the value assigned to it.

Example.cs
var message = "Hello World"; // Compiler knows this is a string
var count = 10;            // Compiler knows this is an int

Professional Tip: Use var when the type is obvious (e.g., var list = new List<string>();). Avoid using var if it makes the code harder for other developers to read.

Type Casting

Sometimes you need to convert a value from one type to another. This is called Casting.

1. Implicit Casting (Automatic)

Happens when you move a smaller type to a larger type. No data loss occurs.

int myInt = 9;
double myDouble = myInt; // Automatic: int becomes double

2. Explicit Casting (Manual)

Required when moving a larger type to a smaller type. This can lead to data loss (truncation).

double myDouble = 9.78;
int myInt = (int)myDouble; // Manual: 9.78 becomes 9 (decimals are dropped)

Constants and Read-Only Fields

If a value should never change during the execution of the program, use the const keyword. This improves performance and prevents accidental bugs.

Constants.cs
const double Pi = 3.14159;
const string CompanyName = "TechCorp Inc";

// Pi = 3.15; // ❌ This will cause a compile-time error

Professional Naming Conventions

In the professional world, following the Microsoft C# Coding Conventions is mandatory for teamwork.

  • camelCase: Used for local variables and method parameters.
    Example: int userAge = 25;
  • PascalCase: Used for Classes, Methods, and Constants.
    Example: public class UserProfile { }
  • Avoid: Single letter names like a, b, x. Use descriptive names like totalInvoiceAmount.
🎯 Professional Lab 2.1: The Financial Calculator

Scenario: You are building a simple billing system for a client.

Requirements: Create a program that does the following:

  1. Declare a const decimal for a Tax Rate (e.g., 0.15 for 15%).
  2. Ask the user to input the Product Name (string).
  3. Ask the user to input the Price of the product (decimal).
  4. Ask the user for the Quantity (int).
  5. Calculate the Subtotal (Price × Quantity).
  6. Calculate the Tax Amount (Subtotal × Tax Rate).
  7. Calculate the Final Total (Subtotal + Tax Amount).
  8. Print a professional receipt including all the above values.

Hint: Use decimal.Parse(Console.ReadLine()) to convert user input to a decimal.

Lecture 03 · Fundamentals

Operators & Expressions

Beginner ~80 min Prerequisite: Lecture 2

What are Operators & Expressions?

An expression is a combination of operators, variables, and values that are evaluated to produce a single result. An operator is a symbol that tells the compiler to perform a specific mathematical or logical manipulation.

Professional Concept: Evaluation

Every expression in C# results in a value. For example, 5 + 2 is an expression that evaluates to the integer 7. In professional software, we aim for "clean" expressions—avoiding overly complex one-liners that are hard for other developers to read.

1. Arithmetic Operators

Used to perform standard mathematical operations.

Operator Name Description Example (int a=10, b=3)
+ Addition Adds two values a + b // 13
- Subtraction Subtracts one value from another a - b // 7
* Multiplication Multiplies two values a * b // 30
/ Division Divides one value by another a / b // 3
% Modulus Returns the division remainder a % b // 1
⚠️ The "Integer Division" Trap

In C#, if you divide two integers, the result is always an integer. Any remainder is simply discarded (truncated).

Example: int result = 5 / 2; will give you 2, not 2.5. To get a decimal result, at least one number must be a double or decimal: double result = 5.0 / 2; // 2.5.

2. Comparison (Relational) Operators

These operators compare two values and always return a bool (true or false). They are the foundation of logic in programming.

  • == Equal to
  • != Not equal to
  • > Greater than
  • < Less than
  • >= Greater than or equal to
  • <= Less than or equal to

3. Logical Operators

Logical operators are used to combine multiple comparison expressions.

  • AND (&&): Returns true only if both statements are true.
  • OR (||): Returns true if at least one statement is true.
  • NOT (!): Reverses the result (true becomes false, false becomes true).
Professional Insight: Short-Circuit Evaluation

C# uses "short-circuiting." In an && operation, if the first condition is false, C# doesn't even check the second condition because the whole thing is already guaranteed to be false. This is used by professionals to prevent crashes (e.g., checking if an object is not null before accessing its properties).

4. Assignment & Compound Operators

Instead of writing x = x + 5, professionals use compound assignments for brevity and clarity.

Shorthand.cs
int score = 100;

score += 10; // Same as: score = score + 10; (110)
score -= 5;   // Same as: score = score - 5;   (105)
score *= 2;   // Same as: score = score * 2;   (210)
score /= 10;  // Same as: score = score / 10;  (21)

5. Professional "Syntactic Sugar"

Modern C# provides shorthand operators that make code cleaner and more readable.

The Ternary Operator (?:)

A compact way to write a simple If-Else statement.

int age = 20;
string status = (age >= 18) ? "Adult" : "Minor";
// If age >= 18 is true, result is "Adult". Otherwise, "Minor".

The Null-Coalescing Operator (??)

Used to provide a default value if a variable is null.

string input = null;
string displayName = input ?? "Guest User";
// If input is null, displayName becomes "Guest User".
🎯 Professional Lab 3.1: E-Commerce Logic Engine

Scenario: You are coding the checkout logic for an online store.

Requirements: Build a program that calculates the final price based on these rules:

  1. Ask user for the Order Total (decimal).
  2. Ask user if they have a Discount Coupon (bool/string).
  3. Rule 1: If the Order Total is over $100, they get a 10% discount.
  4. Rule 2: If they have a coupon AND the order is over $50, they get an additional $5 off.
  5. Rule 3: If the final total is under $20, add a $5 shipping fee. If it's $20 or more, shipping is free.
  6. Final Output: Display the Original Price, Total Discounts applied, and the Final Amount to pay.

Challenge: Try using a Ternary operator to determine the shipping fee message (e.g., "Shipping: Free" or "Shipping: $5").

Lecture 04 · Fundamentals

Control Flow: Decision Making

Beginner ~100 min Prerequisite: Lecture 3

What is Control Flow?

By default, code executes line-by-line from top to bottom. Control Flow allows us to break this linear path, skipping sections of code or executing specific blocks based on whether a condition is true or false.

Professional Concept: Cyclomatic Complexity

In the industry, we track "Cyclomatic Complexity"—a measure of how many independent paths there are through your code. The more nested if statements you have, the higher the complexity, and the harder the code is to test and maintain. Professional code aims for low complexity.

1. Conditional Branching (If, Else If, Else)

The if statement is the most basic form of decision-making. It evaluates a boolean expression and executes a block of code if the result is true.

Logic.cs
int userAge = 20;

if (userAge >= 21) 
{
    Console.WriteLine("Access Granted: Full Access.");
} 
else if (userAge >= 18) 
{
    Console.WriteLine("Access Granted: Limited Access.");
} 
else 
{
    Console.WriteLine("Access Denied: Underage.");
}

Professional Tip: Always use curly braces { } even for single-line statements. It prevents bugs during future code edits.

2. The Switch Statement

When you have a single variable that could be one of many distinct values, a switch statement is cleaner and more performant than multiple else if blocks.

string role = "Admin";

switch (role)
{
    case "Admin":
        Console.WriteLine("Full System Access.");
        break; 
    case "Editor":
        Console.WriteLine("Content Management Access.");
        break;
    case "Guest":
        Console.WriteLine("Read-Only Access.");
        break;
    default:
        Console.WriteLine("Unknown Role: Access Denied.");
        break;
}

The break keyword is mandatory. Without it, the code would "fall through" to the next case, which usually causes a compiler error in C#.

3. Modern C#: Switch Expressions (C# 8.0+)

Professional developers rarely use the old switch statement for simple assignments. They use Switch Expressions, which are more concise and return a value directly.

ModernSwitch.cs
int dayNumber = 3;

string dayName = dayNumber switch
{
    1 => "Monday",
    2 => "Tuesday",
    3 => "Wednesday",
    4 => "Thursday",
    5 => "Friday",
    _ => "Weekend" // The underscore (_) is the default case
};

Console.WriteLine($"Today is {dayName}");

4. Professional Pattern: The Guard Clause

Beginners often write "nested" code that drifts to the right (Arrow Code). Professionals use Guard Clauses to handle errors early and "flatten" the code.

❌ The "Beginner" Way (Nested)
if (user != null) {
    if (user.IsActive) {
        if (user.HasPermission) {
            // Do the actual work here...
        }
    }
}

✅ The "Professional" Way (Guard Clauses)
if (user == null) return; 
if (!user.IsActive) return;
if (!user.HasPermission) return;

// Do the actual work here... (The code stays flat!)
🎯 Professional Lab 4.1: Advanced Access Control System

Scenario: You are building a security module for a corporate building.

Requirements: Create a program that asks for the user's Employee ID and Security Clearance Level (1 to 5).

  1. Requirement 1: If the Employee ID is empty, print "Error: ID Required" and stop. (Use a Guard Clause).
  2. Requirement 2: Use a Switch Expression to determine the Access Level based on the Clearance Level:
    • 1 $\rightarrow$ "Public Area Only"
    • 2 $\rightarrow$ "Office Area"
    • 3 $\rightarrow$ "Server Room"
    • 4 $\rightarrow$ "Executive Suite"
    • 5 $\rightarrow$ "Top Secret Vault"
    • Any other number $\rightarrow$ "Invalid Clearance Level"
  3. Requirement 3: If the Clearance Level is 5 AND the Employee ID is "ADMIN-001", print "Welcome, Director." Otherwise, print the assigned Access Level.
Lecture 05 · Fundamentals

Loops: Mastering Iteration

Beginner ~90 min Prerequisite: Lecture 4

What is Iteration?

Iteration is the process of executing a block of code repeatedly until a specific condition is met. In professional software, loops are used for processing data sets, polling for status changes, or repeating user prompts until valid input is received.

Professional Concept: Time Complexity (Big O)

When you write a loop, you are consuming CPU cycles. A single loop through a list of $n$ items has a time complexity of O(n). However, if you put a loop inside another loop (nested loops), the complexity becomes O(n²). Professionals always strive to minimize nested loops to prevent "performance bottlenecks" as data grows.

1. The for Loop

The for loop is best used when you know exactly how many times the code should run. It is a "counter-driven" loop.

ForLoop.cs
// Structure: (Initialization; Condition; Iterator)
for (int i = 0; i < 5; i++) 
{
    Console.WriteLine($"Processing item number: {i}");
}

Breakdown:
1. int i = 0: Starts the counter.
2. i < 5: The loop runs as long as this is true.
3. i++: Increases the counter by 1 after each loop.

2. The while and do-while Loops

These are "condition-driven" loops. They are used when you don't know how many times the loop will run, but you know when it should stop.

The while Loop (Check then Act)

Checks the condition before executing the block. If the condition is false at the start, the code inside never runs.

bool isRunning = true;
while (isRunning) 
{
    Console.WriteLine("System is scanning...");
    // Logic to eventually set isRunning = false;
}

The do-while Loop (Act then Check)

Executes the block once first, then checks the condition. This guarantees the code runs at least once.

string input;
do 
{
    Console.WriteLine("Please enter 'exit' to stop:");
    input = Console.ReadLine();
} while (input != "exit");

3. The foreach Loop (Industry Standard)

The foreach loop is the most common loop in professional C# development. It is used to iterate through collections (Arrays, Lists, Dictionaries) without needing an index counter.

ForeachExample.cs
string[] employees = { "Alice", "Bob", "Charlie" };

foreach (var name in employees) 
{
    Console.WriteLine($"Sending email to: {name}");
}
⚠️ Professional Warning: The Read-Only Nature

You cannot modify a collection while iterating through it with a foreach loop. If you try to add or remove an item from the list inside a foreach, C# will throw a InvalidOperationException. To modify a list while looping, use a standard for loop and iterate backwards.

4. Loop Control: break and continue

Professionals use these keywords to optimize loops and handle edge cases.

  • break: Immediately terminates the loop and jumps to the code following the loop.
  • continue: Skips the current iteration and jumps immediately to the next cycle of the loop.
for (int i = 1; i <= 10; i++) 
{
    if (i == 3) continue; // Skip 3
    if (i == 7) break;    // Stop entirely at 7
    
    Console.WriteLine(i); // Output: 1, 2, 4, 5, 6
}
🎯 Professional Lab 5.1: Smart Data Processor

Scenario: You are processing a list of server response times (in milliseconds). You need to analyze the data and filter out "noise".

Requirements:

  1. Create an array of integers representing response times: { 120, 450, 80, -10, 1100, 90, 300, -5, 150 }.
  2. Use a foreach loop to iterate through the times.
  3. Rule 1 (Data Cleaning): If a response time is negative, it's an error. Use continue to skip it.
  4. Rule 2 (Critical Failure): If a response time exceeds 1000ms, the server is considered "Crashed". Use break to stop processing immediately.
  5. Rule 3 (Analysis): Calculate the total sum of all valid response times processed.
  6. Final Output: Print the total sum and the number of valid servers processed before the crash (or end of list).
Lecture 06 · Core Concepts

Methods & Parameters

Intermediate ~55 min

What Are Methods?

Methods are reusable blocks of code that perform a specific task. Instead of writing the same logic multiple times, we place that logic inside a method and call it whenever needed.

Methods help make programs:

  • Cleaner and easier to read
  • Reusable and modular
  • Easier to debug and maintain
  • More organized in large applications
void SayHello() {
    Console.WriteLine("Hello World");
}

Once defined, the method can be called anywhere in the program:

SayHello();
SayHello();
SayHello();

Defining Methods

A method definition usually contains:

  • Access modifier (optional)
  • Return type
  • Method name
  • Parameters
  • Method body
static int Add(int x, int y) => x + y;

void Greet(string name, string title = "Dr.") {
    Console.WriteLine($"Hello {title} {name}");
}

Understanding Return Types

The return type tells C# what kind of value the method sends back.

  • int → returns a whole number
  • double → returns decimal values
  • string → returns text
  • bool → returns true or false
  • void → returns nothing
int Square(int number) {
    return number * number;
}

Calling the method:

int result = Square(5);

Console.WriteLine(result);

Method Parameters

Parameters allow methods to receive data from outside. They act like variables that belong to the method.

void DisplayUser(string username, int age) {
    Console.WriteLine(username);
    Console.WriteLine(age);
}

Passing arguments into the method:

DisplayUser("Alex", 22);

Default Parameters

Default parameters provide fallback values when an argument is not supplied. This makes methods more flexible.

void Welcome(string name = "Guest") {
    Console.WriteLine($"Welcome {name}");
}
Welcome();
Welcome("Emma");

Expression-Bodied Methods

Small methods can be shortened using the lambda-style arrow syntax. This creates cleaner and shorter code.

int Multiply(int a, int b) => a * b;

Method Overloading

C# allows multiple methods with the same name as long as their parameters are different.

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

double Add(double a, double b) {
    return a + b;
}

The compiler automatically selects the correct version.

Pass By Value

By default, C# passes arguments by value. This means the method receives a copy of the data.

void ChangeNumber(int num) {
    num = 100;
}

int value = 10;

ChangeNumber(value);

Console.WriteLine(value);

Output:

10

The original variable remains unchanged because only a copy was modified.

Using ref Parameters

The ref keyword passes variables by reference, allowing the method to directly modify the original variable.

void Increase(ref int number) {
    number++;
}

int score = 5;

Increase(ref score);

Console.WriteLine(score);

Using out Parameters

The out keyword is used when a method needs to return multiple values.

void GetValues(out int x, out int y) {
    x = 10;
    y = 20;
}

GetValues(out int a, out int b);

Console.WriteLine(a);
Console.WriteLine(b);

Local Methods

Methods can also exist inside another method. These are called local methods.

void MainMethod() {

    void PrintMessage() {
        Console.WriteLine("Inside Local Method");
    }

    PrintMessage();
}

Best Practices

  • Keep methods short and focused
  • Use meaningful method names
  • Avoid methods that do too many tasks
  • Reuse methods whenever possible
  • Use parameters instead of hardcoded values

Common Mistakes

  • Forgetting the return statement
  • Using the wrong return type
  • Passing incorrect argument types
  • Creating methods with too many parameters
  • Not understanding value vs reference passing

Mini Practice

Try creating the following methods yourself:

  • A method that calculates area of a rectangle
  • A method that checks if a number is even
  • A method that prints a full name
  • A method with a default parameter
  • A method using ref or out
Lecture 07 · Core Concepts

Collections & LINQ

Intermediate ~60 min

What Are Collections?

Collections are data structures used to store and manage groups of objects. Instead of creating multiple individual variables, collections allow us to organize related data efficiently.

C# provides several built-in collection types that are powerful, flexible, and easy to use.

  • Arrays
  • Lists
  • Dictionaries
  • Queues
  • Stacks
  • HashSets

Why Use Collections?

Collections help developers work with large amounts of data dynamically. They make programs cleaner and more scalable.

  • Store multiple values together
  • Add or remove data dynamically
  • Search and sort efficiently
  • Loop through items easily
  • Organize related information

Working with Lists

A List<T> is one of the most commonly used collections in C#. Unlike arrays, lists can grow and shrink dynamically.

var numbers = new List<int> { 10, 20, 30, 40 };

numbers.Add(50);

numbers.RemoveAt(0);

After removing the first element, the list becomes:

20, 30, 40, 50

Adding Items to a List

Use the Add() method to insert new items into a list.

var fruits = new List<string>();

fruits.Add("Apple");
fruits.Add("Banana");
fruits.Add("Orange");

Accessing List Elements

List items are accessed using indexes. Indexes start from 0.

Console.WriteLine(fruits[0]);

Console.WriteLine(fruits[1]);

Looping Through Lists

Lists are commonly used with loops to process every item.

foreach (var item in fruits) {
    Console.WriteLine(item);
}

Useful List Methods

Method Description
Add() Adds a new item
Remove() Removes a specific item
RemoveAt() Removes item by index
Contains() Checks if item exists
Clear() Removes all items
Count Returns total number of items

Using Dictionaries

Dictionaries store data as key-value pairs. They are useful when each item has a unique identifier.

var students = new Dictionary<int, string>();

students.Add(1, "John");
students.Add(2, "Emma");

Console.WriteLine(students[1]);

Understanding LINQ

LINQ stands for Language Integrated Query. It allows developers to query collections using simple and readable syntax.

LINQ works with:

  • Lists
  • Arrays
  • Dictionaries
  • Databases
  • XML data

Introduction to LINQ

LINQ (Language Integrated Query) allows you to query collections like SQL.

var highScores = numbers
    .Where(n => n > 25)
    .OrderByDescending(n => n);

This query:

  • Filters numbers greater than 25
  • Sorts them in descending order

The Where() Method

Where() filters data based on a condition.

var evenNumbers = numbers.Where(n => n % 2 == 0);

Only even numbers will be selected.

The Select() Method

Select() transforms data into another form.

var squared = numbers.Select(n => n * n);

This creates a new collection with squared values.

Sorting Data with LINQ

LINQ provides easy methods for sorting collections.

var ascending = numbers.OrderBy(n => n);

var descending = numbers.OrderByDescending(n => n);

Finding Data

LINQ can quickly search for matching values.

var firstLargeNumber = numbers.First(n => n > 25);

The first number greater than 25 will be returned.

Counting Items

The Count() method returns the total number of matching items.

int total = numbers.Count();

int evenCount = numbers.Count(n => n % 2 == 0);

Combining LINQ Methods

Multiple LINQ methods can be chained together for powerful queries.

var result = numbers
    .Where(n => n > 10)
    .OrderBy(n => n)
    .Select(n => n * 2);

Deferred Execution

Most LINQ queries use deferred execution. This means the query runs only when the data is actually used.

var query = numbers.Where(n => n > 20);

Console.WriteLine(query.Count());

Common LINQ Methods

Method Purpose
Where() Filter data
Select() Transform data
OrderBy() Sort ascending
OrderByDescending() Sort descending
First() Get first matching item
Count() Count items
Any() Check if data exists

Best Practices

  • Use collections instead of many separate variables
  • Choose the correct collection type for the task
  • Keep LINQ queries readable
  • Avoid overly complex chained queries
  • Use meaningful variable names

Common Mistakes

  • Using the wrong collection type
  • Forgetting indexes start at 0
  • Modifying collections during iteration
  • Writing unreadable LINQ chains
  • Ignoring null values in queries

Mini Practice

Try creating the following:

  • A list of student names
  • A dictionary of product prices
  • A LINQ query that finds even numbers
  • A query that sorts numbers descending
  • A query using both Where() and Select()
Lecture 08 · Core Concepts

Strings & Formatting

Beginner ~40 min

What Are Strings?

A string is a sequence of characters used to store text. Strings are one of the most commonly used data types in C#.

Examples of strings:

  • Names
  • Email addresses
  • Messages
  • User input
  • File paths
string name = "John";

string message = "Welcome to C#";

Creating Strings

Strings are written inside double quotation marks.

string city = "London";

string language = "C#";

String Manipulation

C# provides many built-in methods for modifying and working with strings.

string text = "  C# Programming  ";

Console.WriteLine(text.Trim().ToUpper());

Console.WriteLine(text.Contains("C#"));

This example:

  • Removes extra spaces using Trim()
  • Converts text to uppercase using ToUpper()
  • Checks if text contains a value using Contains()

Common String Methods

Method Description
ToUpper() Converts text to uppercase
ToLower() Converts text to lowercase
Trim() Removes extra spaces
Contains() Checks for matching text
Replace() Replaces text
Substring() Extracts part of a string
StartsWith() Checks starting characters
EndsWith() Checks ending characters

Converting Case

Strings can easily be converted between uppercase and lowercase.

string word = "Programming";

Console.WriteLine(word.ToUpper());

Console.WriteLine(word.ToLower());

Replacing Text

The Replace() method changes parts of a string.

string sentence = "I like Java";

sentence = sentence.Replace("Java", "C#");

Console.WriteLine(sentence);

Extracting Text

The Substring() method extracts a portion of a string.

string value = "Programming";

Console.WriteLine(value.Substring(0, 4));

Output:

Prog

Escaping Characters

Escape characters allow special characters inside strings.

Console.WriteLine("She said \"Hello\"");

Console.WriteLine("C:\\Projects\\App");

Verbatim Strings

Verbatim strings use the @ symbol to preserve formatting.

string path = @"
C:\Projects\MyApp\data.txt";

Console.WriteLine(path);

String Concatenation

Concatenation means joining strings together.

string firstName = "John";

string lastName = "Doe";

string fullName = firstName + " " + lastName;

Console.WriteLine(fullName);

String Interpolation

String interpolation is a cleaner way to insert variables into strings.

Console.WriteLine($"Date: {DateTime.Now:d}");

Console.WriteLine($"Price: {19.99:C}"); // Currency

The $ symbol allows variables and expressions inside curly braces.

Formatting Values

C# supports formatting numbers, dates, and currency values.

double price = 99.95;

Console.WriteLine($"{price:C}");

Console.WriteLine($"{price:N2}");

Console.WriteLine($"{price:P}");
Format Meaning
C Currency
N2 Number with 2 decimals
P Percentage
d Short date format

Working with String Length

The Length property returns the number of characters.

string username = "Admin";

Console.WriteLine(username.Length);

Splitting Strings

The Split() method separates text into multiple parts.

string data = "HTML,CSS,JavaScript";

var skills = data.Split(',');

foreach (var skill in skills) {
    Console.WriteLine(skill);
}

Comparing Strings

Strings can be compared using comparison operators or helper methods.

string a = "C#";

string b = "c#";

Console.WriteLine(a == b);

Console.WriteLine(a.Equals(b, StringComparison.OrdinalIgnoreCase));

String Immutability

Strings in C# are immutable. This means their contents cannot be changed after creation.

Methods like Replace() or ToUpper() create new strings instead of modifying the original one.

string textValue = "hello";

string upper = textValue.ToUpper();

Console.WriteLine(textValue);

Console.WriteLine(upper);

Best Practices

  • Use meaningful variable names
  • Prefer string interpolation over concatenation
  • Trim user input when necessary
  • Use formatting for readable output
  • Keep string operations simple and readable

Common Mistakes

  • Forgetting escape characters
  • Using invalid indexes in Substring()
  • Ignoring whitespace in user input
  • Comparing strings with incorrect casing
  • Confusing immutable behavior

Mini Practice

Try creating programs that:

  • Convert text to uppercase
  • Replace words in a sentence
  • Display formatted prices
  • Split a CSV string into values
  • Create a formatted welcome message using interpolation
Lecture 09 · Advanced

Object-Oriented Programming

Advanced ~75 min

Welcome, class. Today we deep-dive into the foundational architecture of scalable software design: Object-Oriented Programming (OOP). As software systems grow in complexity, linear, procedural code inevitably collapses under its own weight. OOP provides us with a framework to manage this complexity by partitioning our programs into self-contained, reusable modules modeled after real-world entities.

The Conceptual Paradigm: Blueprints vs. Artifacts

Before looking at the syntax, you must master the fundamental distinction between a Class and an Object:

  • The Class (The Blueprint): This is an abstract data type. It defines the structure, capabilities, and rules of engagement, but it consumes no operational memory for data storage. It is merely a design.
  • The Object (The Instance): This is the concrete artifact generated from that blueprint. It lives dynamically within your system's RAM, maintaining its own unique state.

Consider the architectural example below written in C#. Here, we define a baseline archetype (Person) and a specialized extension of that archetype (Developer).

public class Person {
    public string Name { get; set; }
    public virtual void Work() => Console.WriteLine("Working...");
}

public class Developer : Person {
    public override void Work() => Console.WriteLine("Coding...");
}

Anatomy of the Mechanics: Inheritance & Polymorphism

Let us break down the underlying mechanics of this code slice. Notice the use of the : operator in Developer : Person. This establishes an IS-A relationship (Inheritance). A Developer is a Person, meaning it automatically inherits the Name property without explicit redeclaration.

However, the real magic happens within the execution behavior, driven by two critical keywords:

  1. virtual: Declared in the base class, this signals to the compiler that this method's behavior is fluid and can be intercepted by derived child classes.
  2. override: Declared in the subclass, this actively intercepts the runtime execution path, substituting the base behavior with a specialized implementation.

Advanced Execution: Dynamic Binding in Action

To fully appreciate why this matters to a software architect, look at how the runtime engine processes these objects when grouped together. Because of polymorphism, a collection typed to the base class can hold any derived class instance seamlessly.

List<Person> team = new List<Person>() {
    new Person { Name = "Professor Smith" },
    new Developer { Name = "Grace Hopper" }
};

foreach (var member in team) {
    Console.Write(member.Name + " execution path: ");
    member.Work(); 
}

When this loop runs, the output demonstrates Dynamic Binding (or late binding). The system determines which method to call at runtime based on the actual object type, not the variable type:

Professor Smith execution path: Working...
Grace Hopper execution path: Coding...

Professor's Lab Task: Expanding the Ecosystem

To reinforce today's lecture, you must complete a practical coding task. Your goal is to introduce a third tier to our organizational hierarchy that introduces unique tracking and alters behavior appropriately.

Your Instructions:

  • Create a new class named Manager that inherits directly from Person.
  • Add an exclusive property to the Manager class: TeamSize (an integer type).
  • Override the Work() method so that it outputs: "Managing a team of [TeamSize] people..." instead of the generic response.
public class Manager : Person {
    // 1. Task: Define your TeamSize property here
    
    // 2. Task: Override the Work() method using string interpolation
}

Verify your solution by creating an instance of your Manager, assigning it a TeamSize of 5, adding it to the team list created above, and confirming that the output shifts dynamically at runtime.

Lecture 10 · Advanced

Exceptions & File I/O

Intermediate ~50 min

Handling Errors

try {
    int x = int.Parse(Console.ReadLine());
} catch (FormatException ex) {
    Console.WriteLine("Invalid number format.");
} finally {
    Console.WriteLine("Done.");
}

Reading/Writing Files

File.WriteAllText("log.txt", "Hello C#");
string content = File.ReadAllText("log.txt");
Lecture 11 · Advanced

The .NET Ecosystem

Intermediate ~45 min

NuGet & Libraries

Use dotnet add package to install community libraries like Newtonsoft.Json.

Asynchronous Programming

public async Task<string> GetDataAsync() {
    var client = new HttpClient();
    return await client.GetStringAsync("https://api.example.com");
}
Lecture 12 · Capstone

Capstone Project: Task Manager

Advanced ~120 min

Build a console-based Task Manager that uses everything we've learned: Lists, LINQ, OOP, and File I/O.

// Project requirements:
// 1. Add/Remove tasks
// 2. Mark tasks as complete
// 3. Save tasks to tasks.json
// 4. Filter tasks using LINQ
Lecture 13 · Advanced

Async & Await

Intermediate ~50 min Requires: Lecture 12

Content coming soon...

Lecture 14 · Advanced

Delegates & Events

Intermediate ~45 min Requires: Lecture 13

Content coming soon...

Lecture 15 · Advanced

Generics & Interfaces

Intermediate ~50 min Requires: Lecture 14

Content coming soon...

Lecture 16 · Professional

Entity Framework & Databases

Advanced ~55 min Requires: Lecture 15

Content coming soon...

Lecture 17 · Professional

Unit Testing (xUnit)

Advanced ~50 min Requires: Lecture 16

Content coming soon...

Lecture 18 · Professional

Final Project — .NET Web API

Advanced ~90 min Requires: All Previous

Content coming soon...