C
h
i
L
L
u
.
.
.

C# Mastery Guide

Complete guide from beginner to advanced

Understanding C#: The Modern .NET Language

C# (pronounced "C Sharp") is a modern, object-oriented, and type-safe programming language developed by Microsoft. Created by Anders Hejlsberg and his team in 2000, C# has evolved into one of the most popular languages for building enterprise applications, games, web services, and mobile apps.

C# runs on the .NET framework and .NET Core, providing a robust ecosystem for building cross-platform applications. It combines the power of C++ with the simplicity of Visual Basic and brings modern features like LINQ, async/await, and pattern matching to developers.

Did you know? C# was originally named "Cool" (C-like Object Oriented Language) but was renamed to C# for trademark reasons. The '#' symbol represents four plus signs, indicating it's a step beyond C++.

1. C# Basics & Syntax

Hello World and Basic Structure

C# programs are organized into namespaces, classes, and methods. The Main method is the entry point of any C# application.
using System;

namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            // Basic output
            Console.WriteLine("Hello, World!");
            
            // Input from user
            Console.Write("Enter your name: ");
            string name = Console.ReadLine();
            Console.WriteLine($"Hello, {name}!");
            
            // Command line arguments
            if (args.Length > 0)
            {
                Console.WriteLine($"First argument: {args[0]}");
            }
        }
    }
}

// Modern C# 9.0+ Top-level statements (no namespace/class required)
using System;

Console.WriteLine("Hello, World!");
Console.Write("Enter your name: ");
string name = Console.ReadLine();
Console.WriteLine($"Hello, {name}!");

Variables and Data Types

C# is a strongly-typed language with value types and reference types. Variables must be declared with a specific type before use.
using System;

class DataTypes
{
    static void Main()
    {
        // Value types
        int age = 25;                    // 32-bit integer
        long bigNumber = 123456789L;     // 64-bit integer
        double price = 19.99;            // Double-precision floating point
        decimal salary = 50000.50M;      // Decimal for financial calculations
        float temperature = 23.5f;       // Single-precision floating point
        char grade = 'A';                // Single character
        bool isActive = true;            // Boolean
        
        // Reference types
        string name = "John Doe";        // String
        object obj = new object();       // Base object type
        dynamic dynamicVar = "Hello";    // Dynamic type (resolved at runtime)
        
        // Nullable value types
        int? nullableInt = null;         // Can hold null
        nullableInt = 42;                // Now has value
        
        // Type inference with var
        var count = 10;                  // Compiler infers int
        var message = "Hello";           // Compiler infers string
        var numbers = new int[] {1, 2, 3}; // Compiler infers int[]
        
        // Constants
        const double PI = 3.14159;
        const string APP_NAME = "My Application";
        
        // Displaying values
        Console.WriteLine($"Name: {name}, Age: {age}");
        Console.WriteLine($"Price: {price:C}");  // Currency format
        Console.WriteLine($"Temperature: {temperature:F1}°C"); // 1 decimal place
        
        // Type information
        Console.WriteLine($"Type of count: {count.GetType()}");
        Console.WriteLine($"Type of message: {message.GetType()}");
    }
}

Operators and Expressions

C# provides a rich set of operators for arithmetic, comparison, logical operations, and more. Understanding operator precedence is crucial.
using System;

class Operators
{
    static void Main()
    {
        // Arithmetic operators
        int a = 10, b = 3;
        int sum = a + b;              // 13
        int difference = a - b;       // 7
        int product = a * b;          // 30
        int quotient = a / b;         // 3 (integer division)
        double realQuotient = (double)a / b; // 3.333...
        int remainder = a % b;        // 1
        int increment = a++;          // Post-increment: 10 (a becomes 11)
        int decrement = --b;          // Pre-decrement: 2 (b becomes 2)
        
        // Assignment operators
        int x = 10;
        x += 5;   // x = x + 5 → 15
        x -= 3;   // x = x - 3 → 12
        x *= 2;   // x = x * 2 → 24
        x /= 4;   // x = x / 4 → 6
        x %= 5;   // x = x % 5 → 1
        
        // Comparison operators
        bool isEqual = (a == b);      // false
        bool notEqual = (a != b);     // true
        bool greaterThan = (a > b);   // true
        bool lessOrEqual = (a <= b);  // false
        
        // Logical operators
        bool condition1 = true, condition2 = false;
        bool andResult = condition1 && condition2;   // false
        bool orResult = condition1 || condition2;    // true
        bool notResult = !condition1;                // false
        
        // Ternary operator
        int number = 15;
        string result = (number % 2 == 0) ? "Even" : "Odd";
        Console.WriteLine($"{number} is {result}");
        
        // Null-coalescing operator
        string nullableString = null;
        string safeString = nullableString ?? "Default Value";
        Console.WriteLine(safeString); // "Default Value"
        
        // Null-conditional operator (C# 6.0+)
        string[] names = null;
        int? length = names?.Length;   // null instead of exception
        string first = names?[0];      // null instead of exception
        
        // Bitwise operators
        int flags = 5;  // Binary: 101
        int mask = 3;   // Binary: 011
        int bitwiseAnd = flags & mask;  // 1 (001)
        int bitwiseOr = flags | mask;   // 7 (111)
        int bitwiseXor = flags ^ mask;  // 6 (110)
        int leftShift = flags << 1;     // 10 (1010)
        int rightShift = flags >> 1;    // 2 (010)
        
        Console.WriteLine($"Bitwise operations: AND={bitwiseAnd}, OR={bitwiseOr}");
    }
}

Control Flow Statements

C# provides comprehensive control flow statements including conditionals, loops, and jump statements for program flow control.
using System;

class ControlFlow
{
    static void Main()
    {
        // If-else statements
        int temperature = 22;
        
        if (temperature > 30)
        {
            Console.WriteLine("It's a hot day!");
            Console.WriteLine("Stay hydrated!");
        }
        else if (temperature > 20)
        {
            Console.WriteLine("Perfect weather!");
            Console.WriteLine("Enjoy outdoors!");
        }
        else
        {
            Console.WriteLine("It's cold outside!");
            Console.WriteLine("Dress warmly!");
        }
        
        // Switch statement
        string day = "Monday";
        
        switch (day)
        {
            case "Monday":
                Console.WriteLine("Start of the work week");
                break;
            case "Friday":
                Console.WriteLine("Weekend is almost here!");
                break;
            case "Saturday":
            case "Sunday":
                Console.WriteLine("Weekend!");
                break;
            default:
                Console.WriteLine("Regular work day");
                break;
        }
        
        // Switch expression (C# 8.0+)
        string message = day switch
        {
            "Monday" => "Start of week",
            "Friday" => "Almost weekend",
            "Saturday" or "Sunday" => "Weekend!",
            _ => "Regular day"
        };
        Console.WriteLine(message);
        
        // While loop
        int count = 1;
        while (count <= 5)
        {
            Console.WriteLine($"While count: {count}");
            count++;
        }
        
        // Do-while loop (executes at least once)
        int number = 1;
        do
        {
            Console.WriteLine($"Do-while number: {number}");
            number++;
        } while (number <= 3);
        
        // For loop
        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine($"For iteration: {i}");
        }
        
        // Foreach loop
        string[] fruits = { "apple", "banana", "orange" };
        foreach (string fruit in fruits)
        {
            Console.WriteLine($"Fruit: {fruit}");
        }
        
        // Loop control statements
        for (int i = 0; i < 10; i++)
        {
            if (i == 3)
                continue;  // Skip this iteration
            
            if (i == 7)
                break;     // Exit loop
            
            Console.WriteLine($"Number: {i}");
        }
        
        // Exception handling with try-catch
        try
        {
            Console.Write("Enter a number: ");
            string input = Console.ReadLine();
            int parsedNumber = int.Parse(input);
            Console.WriteLine($"You entered: {parsedNumber}");
        }
        catch (FormatException)
        {
            Console.WriteLine("Invalid number format!");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
        }
        finally
        {
            Console.WriteLine("This always executes");
        }
    }
}

2. Object-Oriented Programming

Classes and Objects

C# is fundamentally object-oriented. Classes are blueprints for objects, encapsulating data and behavior through properties and methods.
using System;

namespace OOPBasics
{
    // Basic class definition
    public class Person
    {
        // Fields (private by convention)
        private string name;
        private int age;
        
        // Properties (public interface)
        public string Name
        {
            get { return name; }
            set 
            { 
                if (!string.IsNullOrWhiteSpace(value))
                    name = value;
            }
        }
        
        public int Age
        {
            get { return age; }
            set 
            { 
                if (value >= 0 && value <= 150)
                    age = value;
            }
        }
        
        // Auto-implemented property
        public string Email { get; set; }
        
        // Read-only property
        public string DisplayName => $"{Name} ({Age})";
        
        // Constructors
        public Person() { }
        
        public Person(string name, int age)
        {
            Name = name;
            Age = age;
        }
        
        // Methods
        public void Introduce()
        {
            Console.WriteLine($"Hello, my name is {Name} and I am {Age} years old.");
        }
        
        public string GetBirthYear()
        {
            int currentYear = DateTime.Now.Year;
            return $"Born around {currentYear - Age}";
        }
        
        // Static method
        public static void DisplaySpecies()
        {
            Console.WriteLine("Species: Homo sapiens");
        }
    }
    
    class Program
    {
        static void Main()
        {
            // Creating objects
            Person person1 = new Person();
            person1.Name = "John Doe";
            person1.Age = 25;
            person1.Email = "john@example.com";
            
            Person person2 = new Person("Jane Smith", 30);
            
            // Using methods
            person1.Introduce();
            person2.Introduce();
            
            // Using properties
            Console.WriteLine($"{person1.Name}'s display: {person1.DisplayName}");
            Console.WriteLine(person1.GetBirthYear());
            
            // Static method call
            Person.DisplaySpecies();
            
            // Object initializer syntax
            Person person3 = new Person
            {
                Name = "Bob Johnson",
                Age = 35,
                Email = "bob@example.com"
            };
            person3.Introduce();
        }
    }
}

Inheritance and Polymorphism

C# supports inheritance, allowing classes to inherit fields and methods from other classes. Polymorphism enables objects to take many forms.
using System;
using System.Collections.Generic;

namespace OOPAdvanced
{
    // Base class
    public abstract class Animal
    {
        public string Name { get; set; }
        public int Age { get; set; }
        
        // Virtual method - can be overridden
        public virtual void MakeSound()
        {
            Console.WriteLine("Some generic animal sound");
        }
        
        // Abstract method - must be implemented by derived classes
        public abstract void Move();
        
        // Regular method
        public void Sleep()
        {
            Console.WriteLine($"{Name} is sleeping...");
        }
    }
    
    // Interface
    public interface IPet
    {
        string Owner { get; set; }
        void Play();
    }
    
    // Derived class
    public class Dog : Animal, IPet
    {
        public string Breed { get; set; }
        public string Owner { get; set; }
        
        // Constructor
        public Dog(string name, string breed)
        {
            Name = name;
            Breed = breed;
        }
        
        // Override virtual method
        public override void MakeSound()
        {
            Console.WriteLine("Woof! Woof!");
        }
        
        // Implement abstract method
        public override void Move()
        {
            Console.WriteLine($"{Name} is running on four legs");
        }
        
        // Implement interface method
        public void Play()
        {
            Console.WriteLine($"{Name} is playing fetch with {Owner}");
        }
        
        // New method specific to Dog
        public void WagTail()
        {
            Console.WriteLine($"{Name} is wagging its tail");
        }
    }
    
    // Another derived class
    public class Cat : Animal, IPet
    {
        public bool IsIndoor { get; set; }
        public string Owner { get; set; }
        
        public override void MakeSound()
        {
            Console.WriteLine("Meow! Meow!");
        }
        
        public override void Move()
        {
            Console.WriteLine($"{Name} is walking gracefully");
        }
        
        public void Play()
        {
            Console.WriteLine($"{Name} is playing with a ball of yarn");
        }
        
        public void Purr()
        {
            Console.WriteLine($"{Name} is purring...");
        }
    }
    
    class Program
    {
        static void Main()
        {
            // Polymorphism in action
            List<Animal> animals = new List<Animal>
            {
                new Dog("Buddy", "Golden Retriever") { Owner = "John", Age = 3 },
                new Cat("Whiskers", true) { Owner = "Jane", Age = 2 }
            };
            
            foreach (Animal animal in animals)
            {
                Console.WriteLine($"\n{animal.Name}:");
                animal.MakeSound();
                animal.Move();
                animal.Sleep();
                
                // Type checking and casting
                if (animal is IPet pet)
                {
                    pet.Play();
                }
                
                if (animal is Dog dog)
                {
                    dog.WagTail();
                }
                else if (animal is Cat cat)
                {
                    cat.Purr();
                }
            }
            
            // Using interface reference
            IPet myPet = new Dog("Max", "Labrador") { Owner = "Alice" };
            myPet.Play();
        }
    }
    
    // Sealed class - cannot be inherited
    public sealed class FinalClass
    {
        public string Message { get; set; }
    }
    
    // This would cause error:
    // public class DerivedClass : FinalClass { }
}

Encapsulation and Access Modifiers

C# provides access modifiers to control the visibility and accessibility of class members, enabling proper encapsulation.
using System;

namespace EncapsulationExample
{
    public class BankAccount
    {
        // Private fields - only accessible within this class
        private string accountNumber;
        private decimal balance;
        private string accountHolder;
        private DateTime createdDate;
        
        // Public properties with controlled access
        public string AccountNumber 
        { 
            get { return accountNumber; }
            private set { accountNumber = value; }
        }
        
        public decimal Balance
        {
            get { return balance; }
            private set { balance = value; }
        }
        
        public string AccountHolder
        {
            get { return accountHolder; }
            set 
            { 
                if (!string.IsNullOrWhiteSpace(value))
                    accountHolder = value;
            }
        }
        
        public DateTime CreatedDate
        {
            get { return createdDate; }
        }
        
        // Read-only property
        public bool IsActive => Balance >= 0;
        
        // Constructor
        public BankAccount(string accountHolder, string accountNumber, decimal initialDeposit = 0)
        {
            if (initialDeposit < 0)
                throw new ArgumentException("Initial deposit cannot be negative");
                
            AccountHolder = accountHolder;
            this.accountNumber = accountNumber;
            this.balance = initialDeposit;
            this.createdDate = DateTime.Now;
        }
        
        // Public methods to manipulate balance
        public void Deposit(decimal amount)
        {
            if (amount <= 0)
                throw new ArgumentException("Deposit amount must be positive");
                
            balance += amount;
            LogTransaction($"Deposited: {amount:C}");
        }
        
        public bool Withdraw(decimal amount)
        {
            if (amount <= 0)
                throw new ArgumentException("Withdrawal amount must be positive");
                
            if (balance >= amount)
            {
                balance -= amount;
                LogTransaction($"Withdrew: {amount:C}");
                return true;
            }
            
            Console.WriteLine("Insufficient funds!");
            return false;
        }
        
        public void Transfer(BankAccount targetAccount, decimal amount)
        {
            if (targetAccount == null)
                throw new ArgumentNullException(nameof(targetAccount));
                
            if (Withdraw(amount))
            {
                targetAccount.Deposit(amount);
                LogTransaction($"Transferred: {amount:C} to {targetAccount.AccountNumber}");
            }
        }
        
        // Private helper method - only accessible within this class
        private void LogTransaction(string message)
        {
            Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {message}");
            Console.WriteLine($"[Balance: {Balance:C}]");
        }
        
        // Protected method - accessible within this class and derived classes
        protected virtual void OnAccountAction(string action)
        {
            Console.WriteLine($"Account action: {action}");
        }
        
        // Internal method - accessible within the same assembly
        internal void InternalMethod()
        {
            Console.WriteLine("Internal method called");
        }
    }
    
    // Derived class with additional functionality
    public class SavingsAccount : BankAccount
    {
        private decimal interestRate;
        
        public decimal InterestRate
        {
            get { return interestRate; }
            set 
            { 
                if (value >= 0 && value <= 1)
                    interestRate = value;
            }
        }
        
        public SavingsAccount(string accountHolder, string accountNumber, decimal interestRate) 
            : base(accountHolder, accountNumber)
        {
            InterestRate = interestRate;
        }
        
        public void ApplyInterest()
        {
            decimal interest = Balance * InterestRate;
            Deposit(interest);
            OnAccountAction($"Interest applied: {interest:C}");
        }
        
        // Override protected method
        protected override void OnAccountAction(string action)
        {
            base.OnAccountAction(action);
            Console.WriteLine($"Savings Account - {action}");
        }
    }
    
    class Program
    {
        static void Main()
        {
            // Create accounts
            BankAccount checking = new BankAccount("John Doe", "CHK12345", 1000);
            SavingsAccount savings = new SavingsAccount("John Doe", "SAV67890", 0.02m);
            
            // Test operations
            checking.Deposit(500);
            checking.Withdraw(200);
            checking.Transfer(savings, 300);
            
            savings.ApplyInterest();
            
            // Display account information
            Console.WriteLine($"\nChecking Account: {checking.Balance:C}");
            Console.WriteLine($"Savings Account: {savings.Balance:C}");
            Console.WriteLine($"Checking Active: {checking.IsActive}");
            Console.WriteLine($"Account Created: {checking.CreatedDate:yyyy-MM-dd}");
            
            // This would cause errors (private setters):
            // checking.Balance = 1000000; // Error!
            // checking.AccountNumber = "NEW123"; // Error!
        }
    }
}

3. Data Structures & Collections

Arrays and Strings

C# provides robust array and string handling capabilities with extensive built-in methods for manipulation and processing.
using System;

namespace ArraysAndStrings
{
    class Program
    {
        static void Main()
        {
            // Single-dimensional arrays
            int[] numbers = new int[5];
            numbers[0] = 1;
            numbers[1] = 2;
            numbers[2] = 3;
            numbers[3] = 4;
            numbers[4] = 5;
            
            // Array initialization
            int[] primes = { 2, 3, 5, 7, 11 };
            string[] fruits = { "apple", "banana", "orange" };
            
            // Multi-dimensional arrays
            int[,] matrix = new int[3, 3]
            {
                {1, 2, 3},
                {4, 5, 6},
                {7, 8, 9}
            };
            
            // Jagged arrays (array of arrays)
            int[][] jagged = new int[3][];
            jagged[0] = new int[] {1, 2, 3};
            jagged[1] = new int[] {4, 5};
            jagged[2] = new int[] {6, 7, 8, 9};
            
            // Array methods and properties
            Console.WriteLine($"Array length: {numbers.Length}");
            Console.WriteLine($"Array rank: {matrix.Rank}");
            Console.WriteLine($"Array dimensions: {matrix.GetLength(0)}x{matrix.GetLength(1)}");
            
            Array.Sort(primes);
            Array.Reverse(primes);
            int index = Array.IndexOf(primes, 5);
            
            // String basics
            string firstName = "John";
            string lastName = "Doe";
            string fullName = firstName + " " + lastName;
            string interpolated = $"{firstName} {lastName}";
            string formatted = string.Format("{0} {1}", firstName, lastName);
            
            // String methods
            string text = "   Hello, World!   ";
            Console.WriteLine($"Original: '{text}'");
            Console.WriteLine($"Trimmed: '{text.Trim()}'");
            Console.WriteLine($"Upper: {text.ToUpper()}");
            Console.WriteLine($"Lower: {text.ToLower()}");
            Console.WriteLine($"Length: {text.Length}");
            Console.WriteLine($"Contains 'World': {text.Contains("World")}");
            Console.WriteLine($"StartsWith 'Hello': {text.Trim().StartsWith("Hello")}");
            Console.WriteLine($"Index of 'World': {text.IndexOf("World")}");
            
            // String splitting and joining
            string csv = "apple,banana,orange,grape";
            string[] fruitArray = csv.Split(',');
            string joined = string.Join(" - ", fruitArray);
            Console.WriteLine($"Joined: {joined}");
            
            // String building for efficient concatenation
            var sb = new System.Text.StringBuilder();
            for (int i = 0; i < 10; i++)
            {
                sb.Append(i);
                sb.Append(" ");
            }
            string result = sb.ToString();
            Console.WriteLine($"StringBuilder result: {result}");
            
            // String comparison
            string str1 = "hello";
            string str2 = "HELLO";
            bool equal1 = str1 == str2;                    // false
            bool equal2 = str1.Equals(str2);               // false
            bool equal3 = str1.Equals(str2, StringComparison.OrdinalIgnoreCase); // true
            
            Console.WriteLine($"\nString comparisons:");
            Console.WriteLine($"== : {equal1}");
            Console.WriteLine($"Equals: {equal2}");
            Console.WriteLine($"Ignore case: {equal3}");
            
            // String formatting
            DateTime now = DateTime.Now;
            string dateString = string.Format("Today is {0:yyyy-MM-dd} and time is {0:HH:mm:ss}", now);
            Console.WriteLine(dateString);
            
            decimal price = 19.99m;
            Console.WriteLine($"Price: {price:C}");        // Currency
            Console.WriteLine($"Price: {price:F2}");       // Fixed point
            Console.WriteLine($"Large number: {1234567:N0}"); // Number with commas
        }
    }
}

Collections and Generics

C# provides a rich set of collection types in System.Collections.Generic for storing and manipulating groups of objects efficiently.
using System;
using System.Collections.Generic;
using System.Linq;

namespace CollectionsExample
{
    class Program
    {
        static void Main()
        {
            // List<T> - Dynamic array
            List<string> fruits = new List<string> { "apple", "banana" };
            fruits.Add("orange");
            fruits.AddRange(new[] { "grape", "mango" });
            fruits.Insert(1, "kiwi");
            fruits.Remove("banana");
            fruits.RemoveAt(0);
            
            Console.WriteLine("List operations:");
            foreach (string fruit in fruits)
            {
                Console.WriteLine($" - {fruit}");
            }
            Console.WriteLine($"Count: {fruits.Count}");
            Console.WriteLine($"Contains 'orange': {fruits.Contains("orange")}");
            Console.WriteLine($"Index of 'grape': {fruits.IndexOf("grape")}");
            
            // Dictionary<TKey, TValue> - Key-value pairs
            Dictionary<string, int> ages = new Dictionary<string, int>
            {
                ["John"] = 25,
                ["Jane"] = 30,
                ["Bob"] = 35
            };
            
            ages["Alice"] = 28; // Add or update
            ages.TryAdd("Charlie", 40); // Safe add
            
            Console.WriteLine("\nDictionary operations:");
            foreach (KeyValuePair<string, int> kvp in ages)
            {
                Console.WriteLine($" {kvp.Key}: {kvp.Value} years old");
            }
            
            if (ages.TryGetValue("John", out int johnsAge))
            {
                Console.WriteLine($"John's age: {johnsAge}");
            }
            
            // HashSet<T> - Unique elements
            HashSet<int> uniqueNumbers = new HashSet<int> { 1, 2, 3, 4, 5 };
            uniqueNumbers.Add(3); // Won't add duplicate
            uniqueNumbers.Add(6); // Will add new
            
            HashSet<int> otherNumbers = new HashSet<int> { 4, 5, 6, 7, 8 };
            
            Console.WriteLine("\nHashSet operations:");
            Console.WriteLine($"Union: {string.Join(", ", uniqueNumbers.Union(otherNumbers))}");
            Console.WriteLine($"Intersection: {string.Join(", ", uniqueNumbers.Intersect(otherNumbers))}");
            Console.WriteLine($"Difference: {string.Join(", ", uniqueNumbers.Except(otherNumbers))}");
            
            // Queue<T> - FIFO (First In First Out)
            Queue<string> queue = new Queue<string>();
            queue.Enqueue("first");
            queue.Enqueue("second");
            queue.Enqueue("third");
            
            Console.WriteLine("\nQueue operations:");
            while (queue.Count > 0)
            {
                string item = queue.Dequeue();
                Console.WriteLine($"Dequeued: {item}");
            }
            
            // Stack<T> - LIFO (Last In First Out)
            Stack<string> stack = new Stack<string>();
            stack.Push("first");
            stack.Push("second");
            stack.Push("third");
            
            Console.WriteLine("\nStack operations:");
            while (stack.Count > 0)
            {
                string item = stack.Pop();
                Console.WriteLine($"Popped: {item}");
            }
            
            // LinkedList<T> - Doubly linked list
            LinkedList<string> linkedList = new LinkedList<string>();
            linkedList.AddLast("apple");
            linkedList.AddLast("banana");
            linkedList.AddFirst("orange"); // Becomes first
            
            Console.WriteLine("\nLinkedList operations:");
            LinkedListNode<string> currentNode = linkedList.First;
            while (currentNode != null)
            {
                Console.WriteLine($"Node: {currentNode.Value}");
                currentNode = currentNode.Next;
            }
            
            // Sorted collections
            SortedList<string, int> sortedAges = new SortedList<string, int>
            {
                ["Charlie"] = 40,
                ["Alice"] = 28,
                ["Bob"] = 35
            };
            
            Console.WriteLine("\nSortedList (automatically sorted by key):");
            foreach (var kvp in sortedAges)
            {
                Console.WriteLine($" {kvp.Key}: {kvp.Value}");
            }
            
            // Collection initialization with custom objects
            List<Person> people = new List<Person>
            {
                new Person("John", 25),
                new Person("Jane", 30),
                new Person("Bob", 35)
            };
            
            Console.WriteLine("\nCustom objects in collection:");
            foreach (Person person in people)
            {
                Console.WriteLine($" {person.Name} - {person.Age} years");
            }
        }
    }
    
    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
        
        public Person(string name, int age)
        {
            Name = name;
            Age = age;
        }
    }
}

4. Advanced C# Features

Delegates, Events, and Lambdas

C# supports functional programming concepts through delegates, events, and lambda expressions, enabling powerful callback mechanisms and event-driven programming.
using System;

namespace AdvancedFeatures
{
    // Delegate declarations
    public delegate void SimpleDelegate(string message);
    public delegate int MathOperation(int a, int b);
    public delegate bool FilterCondition(int number);
    
    public class Calculator
    {
        // Method that matches MathOperation signature
        public static int Add(int a, int b) => a + b;
        public static int Multiply(int a, int b) => a * b;
        public static int Subtract(int a, int b) => a - b;
    }
    
    // Event publisher class
    public class Button
    {
        // Event declaration
        public event EventHandler<string> Clicked;
        
        public void Click()
        {
            Console.WriteLine("Button was clicked!");
            OnClicked("Button click event raised");
        }
        
        protected virtual void OnClicked(string message)
        {
            Clicked?.Invoke(this, message);
        }
    }
    
    public class AdvancedDemo
    {
        public static void DemonstrateDelegates()
        {
            Console.WriteLine("=== DELEGATES ===");
            
            // Instantiate delegates
            SimpleDelegate simple = PrintMessage;
            MathOperation mathOp = Calculator.Add;
            
            // Invoke delegates
            simple("Hello from delegate!");
            int result = mathOp(10, 5);
            Console.WriteLine($"10 + 5 = {result}");
            
            // Multicast delegates
            SimpleDelegate multi = PrintMessage;
            multi += PrintUpperCase;
            multi += (msg) => Console.WriteLine($"Lambda: {msg}");
            
            multi("Multicast demo");
            
            // Change delegate reference
            mathOp = Calculator.Multiply;
            result = mathOp(10, 5);
            Console.WriteLine($"10 * 5 = {result}");
        }
        
        public static void DemonstrateEvents()
        {
            Console.WriteLine("\n=== EVENTS ===");
            
            Button button = new Button();
            
            // Subscribe to event
            button.Clicked += (sender, message) => 
            {
                Console.WriteLine($"Event handled: {message}");
            };
            
            button.Clicked += Button_Clicked;
            
            // Trigger event
            button.Click();
            
            // Unsubscribe
            button.Clicked -= Button_Clicked;
        }
        
        private static void Button_Clicked(object sender, string message)
        {
            Console.WriteLine($"Additional handler: {message}");
        }
        
        public static void DemonstrateLambdas()
        {
            Console.WriteLine("\n=== LAMBDA EXPRESSIONS ===");
            
            // Lambda expressions
            MathOperation add = (a, b) => a + b;
            MathOperation multiply = (a, b) => a * b;
            
            Console.WriteLine($"Lambda add: {add(7, 3)}");
            Console.WriteLine($"Lambda multiply: {multiply(7, 3)}");
            
            // Using built-in Func and Action delegates
            Func<int, int, int> funcAdd = (a, b) => a + b;
            Action<string> actionPrint = (msg) => Console.WriteLine(msg);
            
            actionPrint($"Func result: {funcAdd(15, 25)}");
            
            // Complex lambda with multiple statements
            Func<int, int, string> complex = (a, b) =>
            {
                int sum = a + b;
                return $"The sum of {a} and {b} is {sum}";
            };
            
            Console.WriteLine(complex(8, 12));
            
            // Using lambda with collections
            int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
            
            // Filter even numbers using lambda
            var evenNumbers = Array.FindAll(numbers, n => n % 2 == 0);
            Console.WriteLine("Even numbers: " + string.Join(", ", evenNumbers));
            
            // Transform numbers using lambda
            var squared = Array.ConvertAll(numbers, n => n * n);
            Console.WriteLine("Squared numbers: " + string.Join(", ", squared));
        }
        
        public static void DemonstrateAnonymousMethods()
        {
            Console.WriteLine("\n=== ANONYMOUS METHODS ===");
            
            // Anonymous method (older syntax)
            MathOperation oldStyle = delegate(int a, int b)
            {
                return a + b;
            };
            
            Console.WriteLine($"Anonymous method: {oldStyle(20, 30)}");
        }
        
        // Method that matches SimpleDelegate signature
        public static void PrintMessage(string message)
        {
            Console.WriteLine($"Message: {message}");
        }
        
        public static void PrintUpperCase(string message)
        {
            Console.WriteLine($"UPPER: {message.ToUpper()}");
        }
    }
    
    class Program
    {
        static void Main()
        {
            AdvancedDemo.DemonstrateDelegates();
            AdvancedDemo.DemonstrateEvents();
            AdvancedDemo.DemonstrateLambdas();
            AdvancedDemo.DemonstrateAnonymousMethods();
        }
    }
}

Extension Methods and Partial Classes

C# allows extending existing types without inheritance through extension methods and splitting class definitions across multiple files using partial classes.
using System;
using System.Collections.Generic;
using System.Text;

namespace ExtensionMethodsDemo
{
    // Extension methods must be in static class
    public static class StringExtensions
    {
        // Extension method for string class
        public static string Reverse(this string str)
        {
            if (string.IsNullOrEmpty(str))
                return str;
                
            char[] charArray = str.ToCharArray();
            Array.Reverse(charArray);
            return new string(charArray);
        }
        
        public static bool IsPalindrome(this string str)
        {
            if (string.IsNullOrEmpty(str))
                return false;
                
            string clean = str.ToLower().Replace(" ", "");
            return clean == clean.Reverse();
        }
        
        public static string ToTitleCase(this string str)
        {
            if (string.IsNullOrEmpty(str))
                return str;
                
            string[] words = str.Split(' ');
            for (int i = 0; i < words.Length; i++)
            {
                if (!string.IsNullOrEmpty(words[i]))
                {
                    words[i] = char.ToUpper(words[i][0]) + words[i].Substring(1).ToLower();
                }
            }
            return string.Join(" ", words);
        }
    }
    
    public static class CollectionExtensions
    {
        public static void PrintAll<T>(this IEnumerable<T> collection)
        {
            Console.WriteLine($"[{string.Join(", ", collection)}]");
        }
        
        public static string ToDelimitedString<T>(this IEnumerable<T> collection, string delimiter = ", ")
        {
            return string.Join(delimiter, collection);
        }
        
        public static bool IsEmpty<T>(this ICollection<T> collection)
        {
            return collection.Count == 0;
        }
    }
    
    public static class NumberExtensions
    {
        public static bool IsEven(this int number) => number % 2 == 0;
        public static bool IsOdd(this int number) => number % 2 != 0;
        public static bool IsPrime(this int number)
        {
            if (number <= 1) return false;
            if (number == 2) return true;
            if (number % 2 == 0) return false;
            
            for (int i = 3; i * i <= number; i += 2)
            {
                if (number % i == 0)
                    return false;
            }
            return true;
        }
        
        public static int Squared(this int number) => number * number;
        public static double ToRadians(this double degrees) => degrees * Math.PI / 180;
        public static double ToDegrees(this double radians) => radians * 180 / Math.PI;
    }
    
    // Partial class example - split across multiple files
    public partial class Employee
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public decimal Salary { get; set; }
        
        public Employee(string firstName, string lastName, decimal salary)
        {
            FirstName = firstName;
            LastName = lastName;
            Salary = salary;
        }
        
        // Partial method declaration (must be void)
        partial void OnSalaryChanged(decimal oldSalary, decimal newSalary);
        
        public void RaiseSalary(decimal amount)
        {
            decimal oldSalary = Salary;
            Salary += amount;
            OnSalaryChanged(oldSalary, Salary); // Call partial method
        }
    }
    
    // Second part of partial class (could be in separate file)
    public partial class Employee
    {
        public string FullName => $"{FirstName} {LastName}";
        
        public string GetInfo()
        {
            return $"{FullName} - Salary: {Salary:C}";
        }
        
        // Implementation of partial method
        partial void OnSalaryChanged(decimal oldSalary, decimal newSalary)
        {
            Console.WriteLine($"Salary changed from {oldSalary:C} to {newSalary:C}");
        }
        
        // Additional methods
        public void DisplayEmployee()
        {
            Console.WriteLine(GetInfo());
        }
    }
    
    class Program
    {
        static void Main()
        {
            Console.WriteLine("=== EXTENSION METHODS ===");
            
            // Using string extensions
            string text = "Hello World";
            Console.WriteLine($"Original: {text}");
            Console.WriteLine($"Reversed: {text.Reverse()}");
            Console.WriteLine($"Title Case: {text.ToTitleCase()}");
            Console.WriteLine($"Is Palindrome 'radar': {"radar".IsPalindrome()}");
            Console.WriteLine($"Is Palindrome 'hello': {"hello".IsPalindrome()}");
            
            // Using collection extensions
            List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
            Console.WriteLine("\nCollection extensions:");
            numbers.PrintAll();
            Console.WriteLine($"Delimited: {numbers.ToDelimitedString(" | ")}");
            Console.WriteLine($"Is empty: {numbers.IsEmpty()}");
            
            // Using number extensions
            int testNumber = 17;
            Console.WriteLine("\nNumber extensions:");
            Console.WriteLine($"{testNumber} is even: {testNumber.IsEven()}");
            Console.WriteLine($"{testNumber} is odd: {testNumber.IsOdd()}");
            Console.WriteLine($"{testNumber} is prime: {testNumber.IsPrime()}");
            Console.WriteLine($"{testNumber} squared: {testNumber.Squared()}");
            
            // Using partial class
            Console.WriteLine("\n=== PARTIAL CLASS ===");
            Employee emp = new Employee("John", "Doe", 50000);
            emp.DisplayEmployee();
            emp.RaiseSalary(10000);
            emp.DisplayEmployee();
            
            // Real-world example: Building a query with extensions
            Console.WriteLine("\n=== PRACTICAL EXAMPLE ===");
            var primes = new List<int>();
            for (int i = 1; i <= 20; i++)
            {
                if (i.IsPrime())
                    primes.Add(i);
            }
            
            Console.WriteLine($"Primes 1-20: {primes.ToDelimitedString()}");
        }
    }
}

5. LINQ & Functional Programming

LINQ Fundamentals

Language Integrated Query (LINQ) provides a consistent way to query various data sources using SQL-like syntax or method syntax with lambda expressions.
using System;
using System.Collections.Generic;
using System.Linq;

namespace LINQFundamentals
{
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Category { get; set; }
        public decimal Price { get; set; }
        public int Stock { get; set; }
        
        public override string ToString() => $"{Name} ({Category}) - {Price:C}";
    }
    
    class Program
    {
        static void Main()
        {
            // Sample data
            List<Product> products = new List<Product>
            {
                new Product { Id = 1, Name = "Laptop", Category = "Electronics", Price = 999.99m, Stock = 10 },
                new Product { Id = 2, Name = "Mouse", Category = "Electronics", Price = 25.50m, Stock = 50 },
                new Product { Id = 3, Name = "Desk", Category = "Furniture", Price = 299.99m, Stock = 5 },
                new Product { Id = 4, Name = "Chair", Category = "Furniture", Price = 149.99m, Stock = 15 },
                new Product { Id = 5, Name = "Monitor", Category = "Electronics", Price = 199.99m, Stock = 8 },
                new Product { Id = 6, Name = "Keyboard", Category = "Electronics", Price = 75.00m, Stock = 25 },
                new Product { Id = 7, Name = "Bookshelf", Category = "Furniture", Price = 179.99m, Stock = 3 },
                new Product { Id = 8, Name = "Tablet", Category = "Electronics", Price = 349.99m, Stock = 12 }
            };
            
            // LINQ Query Syntax
            Console.WriteLine("=== QUERY SYNTAX ===");
            
            // Basic filtering
            var expensiveProducts = from p in products
                                  where p.Price > 100
                                  select p;
            
            Console.WriteLine("Products over $100:");
            foreach (var product in expensiveProducts)
            {
                Console.WriteLine($" - {product}");
            }
            
            // Filtering and ordering
            var electronicsByPrice = from p in products
                                   where p.Category == "Electronics"
                                   orderby p.Price descending
                                   select p;
            
            Console.WriteLine("\nElectronics by price (descending):");
            foreach (var product in electronicsByPrice)
            {
                Console.WriteLine($" - {product}");
            }
            
            // Grouping
            var productsByCategory = from p in products
                                   group p by p.Category into categoryGroup
                                   select new
                                   {
                                       Category = categoryGroup.Key,
                                       Count = categoryGroup.Count(),
                                       TotalValue = categoryGroup.Sum(p => p.Price * p.Stock)
                                   };
            
            Console.WriteLine("\nProducts by category:");
            foreach (var group in productsByCategory)
            {
                Console.WriteLine($" {group.Category}: {group.Count} products, Total value: {group.TotalValue:C}");
            }
            
            // Joining (if we had another collection)
            var categories = new List<string> { "Electronics", "Furniture", "Clothing" };
            
            var categoryProducts = from c in categories
                                 join p in products on c equals p.Category into productGroup
                                 select new
                                 {
                                     Category = c,
                                     Products = productGroup
                                 };
            
            Console.WriteLine("\nProducts by category (with join):");
            foreach (var item in categoryProducts)
            {
                Console.WriteLine($"\n{item.Category}:");
                foreach (var product in item.Products)
                {
                    Console.WriteLine($"   - {product.Name}");
                }
            }
            
            // LINQ Method Syntax
            Console.WriteLine("\n=== METHOD SYNTAX ===");
            
            // Basic filtering
            var cheapProducts = products.Where(p => p.Price < 100);
            Console.WriteLine("Products under $100:");
            cheapProducts.ToList().ForEach(p => Console.WriteLine($" - {p}"));
            
            // Complex queries
            var lowStockElectronics = products
                .Where(p => p.Category == "Electronics" && p.Stock < 15)
                .OrderBy(p => p.Stock)
                .Select(p => new { p.Name, p.Stock, p.Price });
            
            Console.WriteLine("\nLow stock electronics:");
            foreach (var item in lowStockElectronics)
            {
                Console.WriteLine($" - {item.Name}: {item.Stock} in stock, {item.Price:C}");
            }
            
            // Aggregation methods
            Console.WriteLine("\n=== AGGREGATION ===");
            
            decimal totalValue = products.Sum(p => p.Price * p.Stock);
            decimal averagePrice = products.Average(p => p.Price);
            decimal maxPrice = products.Max(p => p.Price);
            decimal minPrice = products.Min(p => p.Price);
            int totalProducts = products.Count();
            
            Console.WriteLine($"Total inventory value: {totalValue:C}");
            Console.WriteLine($"Average price: {averagePrice:C}");
            Console.WriteLine($"Max price: {maxPrice:C}");
            Console.WriteLine($"Min price: {minPrice:C}");
            Console.WriteLine($"Total products: {totalProducts}");
            
            // Element operations
            Console.WriteLine("\n=== ELEMENT OPERATIONS ===");
            
            Product firstProduct = products.First();
            Product lastProduct = products.Last();
            Product singleElectronics = products.First(p => p.Category == "Electronics");
            Product maybeProduct = products.FirstOrDefault(p => p.Price > 1000);
            
            Console.WriteLine($"First product: {firstProduct}");
            Console.WriteLine($"Last product: {lastProduct}");
            Console.WriteLine($"First electronics: {singleElectronics}");
            Console.WriteLine($"Product over $1000: {(maybeProduct?.ToString() ?? "None")}");
            
            // Set operations
            Console.WriteLine("\n=== SET OPERATIONS ===");
            
            List<string> categories1 = new List<string> { "A", "B", "C" };
            List<string> categories2 = new List<string> { "B", "C", "D" };
            
            var union = categories1.Union(categories2);
            var intersect = categories1.Intersect(categories2);
            var except = categories1.Except(categories2);
            
            Console.WriteLine($"Union: {string.Join(", ", union)}");
            Console.WriteLine($"Intersection: {string.Join(", ", intersect)}");
            Console.WriteLine($"Difference: {string.Join(", ", except)}");
            
            // Partitioning
            Console.WriteLine("\n=== PARTITIONING ===");
            
            var firstThree = products.Take(3);
            var skipFirstThree = products.Skip(3);
            var page2 = products.Skip(3).Take(3);
            
            Console.WriteLine("First 3 products:");
            firstThree.ToList().ForEach(p => Console.WriteLine($" - {p}"));
            
            Console.WriteLine("\nProducts after skipping first 3:");
            skipFirstThree.ToList().ForEach(p => Console.WriteLine($" - {p}"));
            
            // Quantifiers
            Console.WriteLine("\n=== QUANTIFIERS ===");
            
            bool hasExpensive = products.Any(p => p.Price > 500);
            bool allHaveStock = products.All(p => p.Stock > 0);
            bool containsLaptop = products.Any(p => p.Name == "Laptop");
            
            Console.WriteLine($"Has expensive products: {hasExpensive}");
            Console.WriteLine($"All products have stock: {allHaveStock}");
            Console.WriteLine($"Contains laptop: {containsLaptop}");
        }
    }
}

Advanced LINQ and Performance

Advanced LINQ features include deferred execution, immediate execution, and performance considerations with PLINQ for parallel processing.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;

namespace AdvancedLINQ
{
    public class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
        public string Major { get; set; }
        public double GPA { get; set; }
        public List<string> Courses { get; set; }
        
        public Student(int id, string name, int age, string major, double gpa)
        {
            Id = id;
            Name = name;
            Age = age;
            Major = major;
            GPA = gpa;
            Courses = new List<string>();
        }
        
        public override string ToString() => $"{Name} ({Major}) - GPA: {GPA:F2}";
    }
    
    class Program
    {
        static void Main()
        {
            var students = new List<Student>
            {
                new Student(1, "Alice", 20, "Computer Science", 3.8) { Courses = { "C#", "Algorithms", "Database" } },
                new Student(2, "Bob", 22, "Mathematics", 3.2) { Courses = { "Calculus", "Statistics", "C#" } },
                new Student(3, "Charlie", 21, "Physics", 3.9) { Courses = { "Physics", "Calculus", "Programming" } },
                new Student(4, "Diana", 19, "Computer Science", 3.5) { Courses = { "C#", "Web Development", "Database" } },
                new Student(5, "Eve", 23, "Mathematics", 3.7) { Courses = { "Statistics", "Algebra", "C#" } },
                new Student(6, "Frank", 20, "Physics", 3.1) { Courses = { "Physics", "Calculus", "Chemistry" } },
                new Student(7, "Grace", 22, "Computer Science", 3.9) { Courses = { "C#", "Algorithms", "AI" } }
            };
            
            // Deferred Execution vs Immediate Execution
            Console.WriteLine("=== DEFERRED EXECUTION ===");
            
            // This query is not executed yet
            var deferredQuery = students.Where(s => s.GPA > 3.5)
                                      .OrderByDescending(s => s.GPA)
                                      .Select(s => new { s.Name, s.GPA });
            
            Console.WriteLine("Query defined but not executed yet");
            
            // Execution happens here (when we iterate)
            Console.WriteLine("Executing query:");
            foreach (var student in deferredQuery)
            {
                Console.WriteLine($" - {student.Name}: {student.GPA:F2}");
            }
            
            // Immediate execution with ToList(), ToArray(), etc.
            var immediateResult = students.Where(s => s.Major == "Computer Science")
                                        .ToList(); // Executes immediately
            
            Console.WriteLine($"\nImmediate execution - CS students: {immediateResult.Count}");
            
            // Complex queries with multiple from clauses (SelectMany)
            Console.WriteLine("\n=== SELECTMANY (FLATTENING) ===");
            
            var allCourses = students.SelectMany(s => s.Courses)
                                   .Distinct()
                                   .OrderBy(course => course);
            
            Console.WriteLine("All unique courses:");
            foreach (var course in allCourses)
            {
                Console.WriteLine($" - {course}");
            }
            
            // Students and their courses
            var studentCourses = from student in students
                               from course in student.Courses
                               select new { student.Name, Course = course };
            
            Console.WriteLine("\nStudents and their courses:");
            foreach (var item in studentCourses.Take(5)) // Show first 5
            {
                Console.WriteLine($" - {item.Name} takes {item.Course}");
            }
            
            // GroupJoin (like SQL LEFT JOIN)
            Console.WriteLine("\n=== GROUPJOIN ===");
            
            var majors = new List<string> { "Computer Science", "Mathematics", "Physics", "Chemistry" };
            
            var studentsByMajor = from major in majors
                                join student in students on major equals student.Major into studentGroup
                                select new
                                {
                                    Major = major,
                                    Students = studentGroup,
                                    Count = studentGroup.Count(),
                                    AverageGPA = studentGroup.Any() ? studentGroup.Average(s => s.GPA) : 0
                                };
            
            foreach (var group in studentsByMajor)
            {
                Console.WriteLine($"\n{group.Major}:");
                Console.WriteLine($"  Count: {group.Count}, Average GPA: {group.AverageGPA:F2}");
                foreach (var student in group.Students)
                {
                    Console.WriteLine($"    - {student.Name} ({student.GPA:F2})");
                }
            }
            
            // Let clause for intermediate results
            Console.WriteLine("\n=== LET CLAUSE ===");
            
            var studentAnalysis = from student in students
                                let grade = student.GPA >= 3.7 ? "A" :
                                           student.GPA >= 3.3 ? "B" :
                                           student.GPA >= 2.7 ? "C" : "D"
                                let status = student.Age >= 21 ? "Senior" : "Junior"
                                select new
                                {
                                    student.Name,
                                    student.Age,
                                    student.GPA,
                                    Grade = grade,
                                    Status = status
                                };
            
            foreach (var analysis in studentAnalysis)
            {
                Console.WriteLine($"{analysis.Name} ({analysis.Status}, Age {analysis.Age}): GPA {analysis.GPA:F2} -> {analysis.Grade}");
            }
            
            // Performance considerations
            Console.WriteLine("\n=== PERFORMANCE ===");
            
            var largeList = Enumerable.Range(1, 1000000).ToList();
            
            var stopwatch = Stopwatch.StartNew();
            
            // Inefficient: Multiple iterations
            var evenNumbers = largeList.Where(x => x % 2 == 0);
            var squared = evenNumbers.Select(x => x * x);
            var result1 = squared.ToList();
            
            stopwatch.Stop();
            Console.WriteLine($"Multiple operations: {stopwatch.ElapsedMilliseconds}ms");
            
            stopwatch.Restart();
            
            // Efficient: Chained operations
            var result2 = largeList.Where(x => x % 2 == 0)
                                 .Select(x => x * x)
                                 .ToList();
            
            stopwatch.Stop();
            Console.WriteLine($"Chained operations: {stopwatch.ElapsedMilliseconds}ms");
            
            // PLINQ (Parallel LINQ)
            Console.WriteLine("\n=== PLINQ (PARALLEL LINQ) ===");
            
            stopwatch.Restart();
            var sequential = largeList.Where(x => x % 2 == 0)
                                    .Select(x => x * x)
                                    .ToList();
            stopwatch.Stop();
            Console.WriteLine($"Sequential: {stopwatch.ElapsedMilliseconds}ms");
            
            stopwatch.Restart();
            var parallel = largeList.AsParallel()
                                  .Where(x => x % 2 == 0)
                                  .Select(x => x * x)
                                  .ToList();
            stopwatch.Stop();
            Console.WriteLine($"Parallel: {stopwatch.ElapsedMilliseconds}ms");
            
            // Custom LINQ methods
            Console.WriteLine("\n=== CUSTOM LINQ METHODS ===");
            
            var topStudents = students.Where(s => s.GPA > 3.5)
                                    .OrderByDescending(s => s.GPA)
                                    .Take(3);
            
            Console.WriteLine("Top 3 students:");
            foreach (var student in topStudents)
            {
                Console.WriteLine($" - {student}");
            }
            
            // Pagination example
            int pageSize = 2;
            int pageNumber = 2;
            
            var page = students.OrderBy(s => s.Name)
                             .Skip((pageNumber - 1) * pageSize)
                             .Take(pageSize);
            
            Console.WriteLine($"\nPage {pageNumber} (size {pageSize}):");
            foreach (var student in page)
            {
                Console.WriteLine($" - {student.Name}");
            }
        }
    }
}

6. Async Programming

Async/Await Fundamentals

C# async/await pattern enables writing asynchronous code that looks synchronous, making it easier to handle I/O-bound operations without blocking threads.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using System.IO;

namespace AsyncProgramming
{
    public class AsyncDemo
    {
        // Basic async method
        public static async Task<string> DownloadWebsiteAsync(string url)
        {
            using (var client = new HttpClient())
            {
                Console.WriteLine($"Starting download from {url}");
                string content = await client.GetStringAsync(url);
                Console.WriteLine($"Download completed from {url}");
                return content;
            }
        }
        
        // Async method with return value
        public static async Task<int> CalculateFactorialAsync(int n)
        {
            Console.WriteLine($"Starting factorial calculation for {n}");
            
            // Simulate CPU-bound work
            await Task.Run(() =>
            {
                for (int i = 1; i <= n; i++)
                {
                    // Simulate work
                    Task.Delay(10).Wait();
                }
            });
            
            int result = 1;
            for (int i = 2; i <= n; i++)
            {
                result *= i;
            }
            
            Console.WriteLine($"Factorial calculation completed for {n}");
            return result;
        }
        
        // Multiple async operations
        public static async Task<List<string>> DownloadMultipleWebsitesAsync(List<string> urls)
        {
            var tasks = new List<Task<string>>();
            
            foreach (string url in urls)
            {
                tasks.Add(DownloadWebsiteAsync(url));
            }
            
            Console.WriteLine("All download tasks started...");
            
            // Wait for all downloads to complete
            string[] results = await Task.WhenAll(tasks);
            
            Console.WriteLine("All downloads completed!");
            return new List<string>(results);
        }
        
        // Async method with exception handling
        public static async Task<string> SafeDownloadAsync(string url)
        {
            try
            {
                using (var client = new HttpClient())
                {
                    client.Timeout = TimeSpan.FromSeconds(10);
                    return await client.GetStringAsync(url);
                }
            }
            catch (HttpRequestException ex)
            {
                Console.WriteLine($"Network error: {ex.Message}");
                return null;
            }
            catch (TaskCanceledException ex)
            {
                Console.WriteLine($"Request timeout: {ex.Message}");
                return null;
            }
        }
        
        // Async file operations
        public static async Task WriteToFileAsync(string filePath, string content)
        {
            Console.WriteLine($"Starting file write to {filePath}");
            
            // Ensure directory exists
            string directory = Path.GetDirectoryName(filePath);
            if (!Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }
            
            await File.WriteAllTextAsync(filePath, content);
            Console.WriteLine($"File write completed: {filePath}");
        }
        
        public static async Task<string> ReadFromFileAsync(string filePath)
        {
            if (!File.Exists(filePath))
            {
                throw new FileNotFoundException($"File not found: {filePath}");
            }
            
            Console.WriteLine($"Starting file read from {filePath}");
            string content = await File.ReadAllTextAsync(filePath);
            Console.WriteLine($"File read completed: {filePath}");
            return content;
        }
        
        // Cancellation support
        public static async Task LongRunningOperationAsync(
            int durationSeconds, 
            System.Threading.CancellationToken cancellationToken = default)
        {
            Console.WriteLine($"Starting long operation for {durationSeconds} seconds");
            
            for (int i = 1; i <= durationSeconds; i++)
            {
                // Check for cancellation
                cancellationToken.ThrowIfCancellationRequested();
                
                Console.WriteLine($"Progress: {i}/{durationSeconds} seconds");
                await Task.Delay(1000, cancellationToken);
            }
            
            Console.WriteLine("Long operation completed!");
        }
        
        // Async properties and constructors (not allowed)
        // public async string AsyncProperty { get; set; } // Error!
        
        // Async event handlers
        public static async void ProcessButtonClick(object sender, EventArgs e)
        {
            try
            {
                Console.WriteLine("Button clicked - starting async processing");
                await DownloadWebsiteAsync("https://example.com");
                Console.WriteLine("Button click processing completed");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error in button click: {ex.Message}");
            }
        }
    }
    
    // Async repository pattern
    public interface IUserRepository
    {
        Task<User> GetUserByIdAsync(int id);
        Task<List<User>> GetAllUsersAsync();
        Task AddUserAsync(User user);
        Task UpdateUserAsync(User user);
        Task DeleteUserAsync(int id);
    }
    
    public class User
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Email { get; set; }
    }
    
    public class MockUserRepository : IUserRepository
    {
        private readonly List<User> _users = new List<User>
        {
            new User { Id = 1, Name = "Alice", Email = "alice@example.com" },
            new User { Id = 2, Name = "Bob", Email = "bob@example.com" },
            new User { Id = 3, Name = "Charlie", Email = "charlie@example.com" }
        };
        
        public async Task<User> GetUserByIdAsync(int id)
        {
            Console.WriteLine($"Getting user {id} from repository");
            
            // Simulate database access delay
            await Task.Delay(100);
            
            return _users.Find(u => u.Id == id);
        }
        
        public async Task<List<User>> GetAllUsersAsync()
        {
            Console.WriteLine("Getting all users from repository");
            await Task.Delay(200);
            return new List<User>(_users);
        }
        
        public async Task AddUserAsync(User user)
        {
            Console.WriteLine($"Adding user: {user.Name}");
            await Task.Delay(150);
            _users.Add(user);
        }
        
        public async Task UpdateUserAsync(User user)
        {
            Console.WriteLine($"Updating user: {user.Name}");
            await Task.Delay(150);
            
            var existingUser = _users.Find(u => u.Id == user.Id);
            if (existingUser != null)
            {
                existingUser.Name = user.Name;
                existingUser.Email = user.Email;
            }
        }
        
        public async Task DeleteUserAsync(int id)
        {
            Console.WriteLine($"Deleting user {id}");
            await Task.Delay(100);
            _users.RemoveAll(u => u.Id == id);
        }
    }
    
    class Program
    {
        static async Task Main(string[] args)
        {
            Console.WriteLine("=== ASYNC/AWAIT DEMONSTRATION ===\n");
            
            // Basic async call
            Console.WriteLine("1. Basic async download:");
            string content = await AsyncDemo.DownloadWebsiteAsync("https://httpbin.org/json");
            Console.WriteLine($"Downloaded {content?.Length ?? 0} characters\n");
            
            // Multiple async operations
            Console.WriteLine("2. Multiple async operations:");
            var urls = new List<string>
            {
                "https://httpbin.org/delay/1",
                "https://httpbin.org/delay/2",
                "https://httpbin.org/delay/1"
            };
            
            var results = await AsyncDemo.DownloadMultipleWebsitesAsync(urls);
            Console.WriteLine($"Downloaded {results.Count} websites\n");
            
            // Async with cancellation
            Console.WriteLine("3. Async with cancellation:");
            using (var cts = new System.Threading.CancellationTokenSource())
            {
                // Cancel after 3 seconds
                cts.CancelAfter(3000);
                
                try
                {
                    await AsyncDemo.LongRunningOperationAsync(5, cts.Token);
                }
                catch (OperationCanceledException)
                {
                    Console.WriteLine("Operation was cancelled!\n");
                }
            }
            
            // File operations
            Console.WriteLine("4. Async file operations:");
            string testFile = "test.txt";
            await AsyncDemo.WriteToFileAsync(testFile, "Hello, async file operations!");
            string fileContent = await AsyncDemo.ReadFromFileAsync(testFile);
            Console.WriteLine($"File content: {fileContent}\n");
            
            // Repository pattern
            Console.WriteLine("5. Async repository pattern:");
            IUserRepository userRepo = new MockUserRepository();
            
            var users = await userRepo.GetAllUsersAsync();
            Console.WriteLine($"Retrieved {users.Count} users");
            
            var user = await userRepo.GetUserByIdAsync(1);
            Console.WriteLine($"Retrieved user: {user?.Name}\n");
            
            // ValueTask example for performance
            Console.WriteLine("6. ValueTask for high-performance scenarios:");
            await UseValueTaskExample();
            
            Console.WriteLine("\nAll async operations completed!");
        }
        
        static async ValueTask UseValueTaskExample()
        {
            // ValueTask is more efficient for synchronous completion
            var result = await GetCachedValueAsync();
            Console.WriteLine($"ValueTask result: {result}");
        }
        
        static async ValueTask<int> GetCachedValueAsync()
        {
            // If we have cached value, return synchronously
            if (DateTime.Now.Second % 2 == 0) // Simple cache simulation
            {
                return 42; // Synchronous completion
            }
            
            // Otherwise, perform async operation
            await Task.Delay(100);
            return 100;
        }
    }
}

Advanced Async Patterns

Advanced async patterns include async streams, task composition, parallelism, and proper error handling in asynchronous scenarios.
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Threading;
using System.Linq;

namespace AdvancedAsyncPatterns
{
    // Async disposable pattern
    public class AsyncResource : IAsyncDisposable
    {
        private bool _disposed = false;
        
        public async Task ProcessDataAsync()
        {
            Console.WriteLine("Processing data asynchronously...");
            await Task.Delay(1000);
            Console.WriteLine("Data processing completed");
        }
        
        public async ValueTask DisposeAsync()
        {
            if (!_disposed)
            {
                Console.WriteLine("Disposing async resources...");
                await Task.Delay(500); // Simulate async cleanup
                _disposed = true;
                Console.WriteLine("Async disposal completed");
            }
        }
    }
    
    // Async lazy initialization
    public class AsyncLazy<T>
    {
        private readonly Func<Task<T>> _factory;
        private Lazy<Task<T>> _lazyTask;
        
        public AsyncLazy(Func<Task<T>> factory)
        {
            _factory = factory;
            _lazyTask = new Lazy<Task<T>>(() => _factory());
        }
        
        public Task<T> Value => _lazyTask.Value;
        
        public bool IsValueCreated => _lazyTask.IsValueCreated;
    }
    
    // Async event with semaphore for thread safety
    public class AsyncEventPublisher
    {
        private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
        private event Func<string, Task> AsyncEvent;
        
        public async Task SubscribeAsync(Func<string, Task> handler)
        {
            await _semaphore.WaitAsync();
            try
            {
                AsyncEvent += handler;
            }
            finally
            {
                _semaphore.Release();
            }
        }
        
        public async Task UnsubscribeAsync(Func<string, Task> handler)
        {
            await _semaphore.WaitAsync();
            try
            {
                AsyncEvent -= handler;
            }
            finally
            {
                _semaphore.Release();
            }
        }
        
        public async Task PublishAsync(string message)
        {
            Func<string, Task> handlers;
            
            await _semaphore.WaitAsync();
            try
            {
                handlers = AsyncEvent;
            }
            finally
            {
                _semaphore.Release();
            }
            
            if (handlers != null)
            {
                var invocationTasks = handlers.GetInvocationList()
                    .Cast<Func<string, Task>>()
                    .Select(handler => handler(message));
                
                await Task.WhenAll(invocationTasks);
            }
        }
    }
    
    // Async producer-consumer pattern
    public class AsyncProducerConsumer<T>
    {
        private readonly Queue<T> _queue = new Queue<T>();
        private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(0);
        private readonly object _lock = new object();
        private bool _completed = false;
        
        public void Produce(T item)
        {
            lock (_lock)
            {
                if (_completed)
                    throw new InvalidOperationException("Production completed");
                
                _queue.Enqueue(item);
                _semaphore.Release();
            }
        }
        
        public async Task<T> ConsumeAsync(CancellationToken cancellationToken = default)
        {
            await _semaphore.WaitAsync(cancellationToken);
            
            lock (_lock)
            {
                return _queue.Dequeue();
            }
        }
        
        public void Complete()
        {
            lock (_lock)
            {
                _completed = true;
            }
        }
    }
    
    // Async streams (IAsyncEnumerable) - C# 8.0+
    public static class AsyncStreams
    {
        public static async IAsyncEnumerable<int> GenerateNumbersAsync(int count)
        {
            for (int i = 1; i <= count; i++)
            {
                await Task.Delay(100); // Simulate async work
                yield return i;
            }
        }
        
        public static async IAsyncEnumerable<string> SimulateDataStreamAsync()
        {
            var dataPoints = new[] { "A", "B", "C", "D", "E" };
            
            foreach (var point in dataPoints)
            {
                await Task.Delay(200); // Simulate async data arrival
                yield return point;
            }
        }
        
        public static async Task ProcessStreamAsync()
        {
            await foreach (var number in GenerateNumbersAsync(5))
            {
                Console.WriteLine($"Received: {number}");
            }
        }
    }
    
    // Task completion source for custom async operations
    public class AsyncOperation<T>
    {
        private readonly TaskCompletionSource<T> _tcs = new TaskCompletionSource<T>();
        
        public Task<T> Task => _tcs.Task;
        
        public void SetResult(T result) => _tcs.SetResult(result);
        public void SetException(Exception exception) => _tcs.SetException(exception);
        public void SetCanceled() => _tcs.SetCanceled();
    }
    
    // Retry pattern with exponential backoff
    public static class RetryHelper
    {
        public static async Task<T> RetryAsync<T>(
            Func<Task<T>> operation,
            int maxRetries = 3,
            TimeSpan initialDelay = default,
            Func<Exception, bool> shouldRetry = null)
        {
            if (initialDelay == default)
                initialDelay = TimeSpan.FromSeconds(1);
            
            var exceptions = new List<Exception>();
            
            for (int retryCount = 0; retryCount <= maxRetries; retryCount++)
            {
                try
                {
                    return await operation();
                }
                catch (Exception ex) when (shouldRetry?.Invoke(ex) ?? true)
                {
                    exceptions.Add(ex);
                    
                    if (retryCount == maxRetries)
                        break;
                    
                    TimeSpan delay = TimeSpan.FromSeconds(Math.Pow(2, retryCount)) + initialDelay;
                    Console.WriteLine($"Retry {retryCount + 1}/{maxRetries} after {delay}");
                    await Task.Delay(delay);
                }
            }
            
            throw new AggregateException("Operation failed after all retries", exceptions);
        }
    }
    
    class Program
    {
        static async Task Main(string[] args)
        {
            Console.WriteLine("=== ADVANCED ASYNC PATTERNS ===\n");
            
            // Async disposable
            Console.WriteLine("1. Async Disposable Pattern:");
            await using (var resource = new AsyncResource())
            {
                await resource.ProcessDataAsync();
            }
            Console.WriteLine();
            
            // Async lazy
            Console.WriteLine("2. Async Lazy Initialization:");
            var lazyValue = new AsyncLazy<string>(async () =>
            {
                Console.WriteLine("Computing lazy value...");
                await Task.Delay(1000);
                return "Lazy result";
            });
            
            Console.WriteLine("Accessing lazy value...");
            string result = await lazyValue.Value;
            Console.WriteLine($"Lazy value: {result}\n");
            
            // Async streams
            Console.WriteLine("3. Async Streams:");
            await foreach (var item in AsyncStreams.GenerateNumbersAsync(3))
            {
                Console.WriteLine($"Stream item: {item}");
            }
            Console.WriteLine();
            
            // Producer-consumer pattern
            Console.WriteLine("4. Async Producer-Consumer:");
            var producerConsumer = new AsyncProducerConsumer<int>();
            var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
            
            _ = Task.Run(async () =>
            {
                for (int i = 1; i <= 3; i++)
                {
                    await Task.Delay(500);
                    producerConsumer.Produce(i);
                    Console.WriteLine($"Produced: {i}");
                }
                producerConsumer.Complete();
            });
            
            try
            {
                while (true)
                {
                    var item = await producerConsumer.ConsumeAsync(cts.Token);
                    Console.WriteLine($"Consumed: {item}");
                }
            }
            catch (OperationCanceledException)
            {
                Console.WriteLine("Consumption cancelled\n");
            }
            
            // Retry pattern
            Console.WriteLine("5. Retry Pattern with Exponential Backoff:");
            int attempt = 0;
            var retryResult = await RetryHelper.RetryAsync(async () =>
            {
                attempt++;
                Console.WriteLine($"Attempt {attempt}");
                
                if (attempt < 3)
                {
                    throw new InvalidOperationException($"Simulated failure {attempt}");
                }
                
                await Task.Delay(100);
                return "Success!";
            }, maxRetries: 3);
            
            Console.WriteLine($"Retry result: {retryResult}\n");
            
            // Task composition
            Console.WriteLine("6. Advanced Task Composition:");
            await TaskCompositionExamples();
            
            Console.WriteLine("All advanced async patterns demonstrated!");
        }
        
        static async Task TaskCompositionExamples()
        {
            var tasks = new[]
            {
                Task.Delay(1000).ContinueWith(_ => "First"),
                Task.Delay(500).ContinueWith(_ => "Second"),
                Task.Delay(1500).ContinueWith(_ => "Third")
            };
            
            // Wait for all tasks
            var allResults = await Task.WhenAll(tasks);
            Console.WriteLine($"WhenAll results: {string.Join(", ", allResults)}");
            
            // Wait for any task
            var firstResult = await Task.WhenAny(tasks);
            Console.WriteLine($"WhenAny first result: {await firstResult}");
            
            // ContinueWith for task chaining
            var complexTask = Task.Run(() => 10)
                .ContinueWith(t => t.Result * 2)
                .ContinueWith(t => $"Result: {t.Result}")
                .ContinueWith(t => t.Result.ToUpper());
            
            Console.WriteLine($"Chained task result: {await complexTask}");
        }
    }
}

7. Web Development with ASP.NET

ASP.NET Core Web API

ASP.NET Core is a cross-platform, high-performance framework for building modern, cloud-based, internet-connected applications. Web APIs are perfect for building RESTful services.
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.Collections.Generic;
using System.Text.Json;

// Minimal API example (ASP.NET Core 6.0+)
var builder = WebApplication.CreateBuilder(args);

// Add services to the container
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

// In-memory data store
var users = new List<User>
{
    new User(1, "John Doe", "john@example.com"),
    new User(2, "Jane Smith", "jane@example.com"),
    new User(3, "Bob Johnson", "bob@example.com")
};

// API endpoints using minimal APIs
app.MapGet("/api/users", () => Results.Ok(users));

app.MapGet("/api/users/{id}", (int id) =>
{
    var user = users.Find(u => u.Id == id);
    return user != null ? Results.Ok(user) : Results.NotFound();
});

app.MapPost("/api/users", (User user) =>
{
    user.Id = users.Count > 0 ? users.Max(u => u.Id) + 1 : 1;
    users.Add(user);
    return Results.Created($"/api/users/{user.Id}", user);
});

app.MapPut("/api/users/{id}", (int id, User updatedUser) =>
{
    var existingUser = users.Find(u => u.Id == id);
    if (existingUser == null)
        return Results.NotFound();
    
    existingUser.Name = updatedUser.Name;
    existingUser.Email = updatedUser.Email;
    return Results.Ok(existingUser);
});

app.MapDelete("/api/users/{id}", (int id) =>
{
    var user = users.Find(u => u.Id == id);
    if (user == null)
        return Results.NotFound();
    
    users.Remove(user);
    return Results.NoContent();
});

// Health check endpoint
app.MapGet("/health", () => new { status = "Healthy", timestamp = DateTime.UtcNow });

// File upload endpoint
app.MapPost("/api/upload", async (HttpRequest request) =>
{
    if (!request.HasFormContentType)
        return Results.BadRequest("Expected form data");
    
    var form = await request.ReadFormAsync();
    var file = form.Files["file"];
    
    if (file == null || file.Length == 0)
        return Results.BadRequest("No file uploaded");
    
    // Process the file
    var fileInfo = new
    {
        FileName = file.FileName,
        ContentType = file.ContentType,
        Size = file.Length,
        UploadedAt = DateTime.UtcNow
    };
    
    return Results.Ok(fileInfo);
});

app.Run();

// Record type for immutable data (C# 9.0+)
public record User(int Id, string Name, string Email);

// Traditional Controller-based API (for comparison)
/*
[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
    private static readonly List<User> _users = new();
    
    [HttpGet]
    public IActionResult GetUsers() => Ok(_users);
    
    [HttpGet("{id}")]
    public IActionResult GetUser(int id)
    {
        var user = _users.Find(u => u.Id == id);
        return user != null ? Ok(user) : NotFound();
    }
    
    [HttpPost]
    public IActionResult CreateUser(User user)
    {
        user.Id = _users.Count > 0 ? _users.Max(u => u.Id) + 1 : 1;
        _users.Add(user);
        return CreatedAtAction(nameof(GetUser), new { id = user.Id }, user);
    }
    
    [HttpPut("{id}")]
    public IActionResult UpdateUser(int id, User updatedUser)
    {
        var existingUser = _users.Find(u => u.Id == id);
        if (existingUser == null)
            return NotFound();
        
        existingUser.Name = updatedUser.Name;
        existingUser.Email = updatedUser.Email;
        return Ok(existingUser);
    }
    
    [HttpDelete("{id}")]
    public IActionResult DeleteUser(int id)
    {
        var user = _users.Find(u => u.Id == id);
        if (user == null)
            return NotFound();
        
        _users.Remove(user);
        return NoContent();
    }
}
*/

MVC Pattern and Razor Pages

ASP.NET Core MVC provides a patterns-based way to build dynamic websites with clean separation of concerns. Razor Pages is a page-based programming model that makes building web UI easier.
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;

// MVC Controller example
[Route("products")]
public class ProductsController : Controller
{
    private readonly IProductService _productService;
    
    public ProductsController(IProductService productService)
    {
        _productService = productService;
    }
    
    [HttpGet]
    public async Task<IActionResult> Index(string category = null, int page = 1)
    {
        var products = await _productService.GetProductsAsync(category, page, 10);
        var categories = await _productService.GetCategoriesAsync();
        
        var viewModel = new ProductIndexViewModel
        {
            Products = products,
            Categories = categories,
            SelectedCategory = category,
            CurrentPage = page
        };
        
        return View(viewModel);
    }
    
    [HttpGet("{id}")]
    public async Task<IActionResult> Details(int id)
    {
        var product = await _productService.GetProductByIdAsync(id);
        if (product == null)
            return NotFound();
            
        return View(product);
    }
    
    [HttpGet("create")]
    public IActionResult Create()
    {
        return View(new ProductCreateModel());
    }
    
    [HttpPost("create")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Create(ProductCreateModel model)
    {
        if (!ModelState.IsValid)
            return View(model);
        
        var product = new Product
        {
            Name = model.Name,
            Description = model.Description,
            Price = model.Price,
            Category = model.Category
        };
        
        await _productService.CreateProductAsync(product);
        return RedirectToAction(nameof(Index));
    }
    
    [HttpGet("edit/{id}")]
    public async Task<IActionResult> Edit(int id)
    {
        var product = await _productService.GetProductByIdAsync(id);
        if (product == null)
            return NotFound();
            
        var model = new ProductEditModel
        {
            Id = product.Id,
            Name = product.Name,
            Description = product.Description,
            Price = product.Price,
            Category = product.Category
        };
        
        return View(model);
    }
    
    [HttpPost("edit/{id}")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Edit(int id, ProductEditModel model)
    {
        if (id != model.Id)
            return BadRequest();
        
        if (!ModelState.IsValid)
            return View(model);
        
        var product = await _productService.GetProductByIdAsync(id);
        if (product == null)
            return NotFound();
        
        product.Name = model.Name;
        product.Description = model.Description;
        product.Price = model.Price;
        product.Category = model.Category;
        
        await _productService.UpdateProductAsync(product);
        return RedirectToAction(nameof(Index));
    }
    
    [HttpPost("delete/{id}")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Delete(int id)
    {
        await _productService.DeleteProductAsync(id);
        return RedirectToAction(nameof(Index));
    }
}

// Razor Pages example
public class ProductDetailsModel : PageModel
{
    private readonly IProductService _productService;
    
    public ProductDetailsModel(IProductService productService)
    {
        _productService = productService;
    }
    
    public Product Product { get; set; }
    
    public async Task<IActionResult> OnGetAsync(int id)
    {
        Product = await _productService.GetProductByIdAsync(id);
        if (Product == null)
            return NotFound();
            
        return Page();
    }
    
    public async Task<IActionResult> OnPostAddToCartAsync(int productId, int quantity)
    {
        var product = await _productService.GetProductByIdAsync(productId);
        if (product == null)
            return NotFound();
        
        // Add to shopping cart logic
        TempData["Message"] = $"{product.Name} added to cart!";
        return RedirectToPage("/Cart/Index");
    }
}

// View Models
public class ProductIndexViewModel
{
    public List<Product> Products { get; set; }
    public List<string> Categories { get; set; }
    public string SelectedCategory { get; set; }
    public int CurrentPage { get; set; }
    public int TotalPages { get; set; }
}

public class ProductCreateModel
{
    [Required]
    [StringLength(100)]
    public string Name { get; set; }
    
    [StringLength(500)]
    public string Description { get; set; }
    
    [Required]
    [Range(0.01, 10000)]
    public decimal Price { get; set; }
    
    [Required]
    public string Category { get; set; }
}

public class ProductEditModel
{
    public int Id { get; set; }
    
    [Required]
    [StringLength(100)]
    public string Name { get; set; }
    
    [StringLength(500)]
    public string Description { get; set; }
    
    [Required]
    [Range(0.01, 10000)]
    public decimal Price { get; set; }
    
    [Required]
    public string Category { get; set; }
}

// Entity Framework Context
public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
    
    public DbSet<Product> Products { get; set; }
    public DbSet<Category> Categories { get; set; }
    
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Product>(entity =>
        {
            entity.HasKey(e => e.Id);
            entity.Property(e => e.Name).IsRequired().HasMaxLength(100);
            entity.Property(e => e.Price).HasColumnType("decimal(18,2)");
            entity.HasIndex(e => e.Category);
        });
    }
}

// Service interface
public interface IProductService
{
    Task<List<Product>> GetProductsAsync(string category = null, int page = 1, int pageSize = 10);
    Task<Product> GetProductByIdAsync(int id);
    Task<List<string>> GetCategoriesAsync();
    Task CreateProductAsync(Product product);
    Task UpdateProductAsync(Product product);
    Task DeleteProductAsync(int id);
}

// Service implementation
public class ProductService : IProductService
{
    private readonly AppDbContext _context;
    
    public ProductService(AppDbContext context)
    {
        _context = context;
    }
    
    public async Task<List<Product>> GetProductsAsync(string category = null, int page = 1, int pageSize = 10)
    {
        var query = _context.Products.AsQueryable();
        
        if (!string.IsNullOrEmpty(category))
        {
            query = query.Where(p => p.Category == category);
        }
        
        return await query
            .OrderBy(p => p.Name)
            .Skip((page - 1) * pageSize)
            .Take(pageSize)
            .ToListAsync();
    }
    
    public async Task<Product> GetProductByIdAsync(int id)
    {
        return await _context.Products.FindAsync(id);
    }
    
    public async Task<List<string>> GetCategoriesAsync()
    {
        return await _context.Products
            .Select(p => p.Category)
            .Distinct()
            .OrderBy(c => c)
            .ToListAsync();
    }
    
    public async Task CreateProductAsync(Product product)
    {
        _context.Products.Add(product);
        await _context.SaveChangesAsync();
    }
    
    public async Task UpdateProductAsync(Product product)
    {
        _context.Products.Update(product);
        await _context.SaveChangesAsync();
    }
    
    public async Task DeleteProductAsync(int id)
    {
        var product = await _context.Products.FindAsync(id);
        if (product != null)
        {
            _context.Products.Remove(product);
            await _context.SaveChangesAsync();
        }
    }
}

// Models
public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public decimal Price { get; set; }
    public string Category { get; set; }
    public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
    public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
}

public class Category
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
}

8. Database & Entity Framework

Entity Framework Core

Entity Framework Core is a modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace EFCoreExample
{
    // DbContext - the main class that coordinates EF functionality
    public class BloggingContext : DbContext
    {
        public DbSet<Blog> Blogs { get; set; }
        public DbSet<Post> Posts { get; set; }
        public DbSet<Tag> Tags { get; set; }
        public DbSet<Author> Authors { get; set; }
        
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer(
                @"Server=(localdb)\mssqllocaldb;Database=Blogging;Trusted_Connection=True");
        }
        
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            // Configure relationships and constraints
            modelBuilder.Entity<Blog>()
                .HasMany(b => b.Posts)
                .WithOne(p => p.Blog)
                .HasForeignKey(p => p.BlogId)
                .OnDelete(DeleteBehavior.Cascade);
            
            modelBuilder.Entity<Post>()
                .HasMany(p => p.Tags)
                .WithMany(t => t.Posts)
                .UsingEntity(j => j.ToTable("PostTags"));
            
            modelBuilder.Entity<Author>()
                .HasIndex(a => a.Email)
                .IsUnique();
            
            // Seed data
            modelBuilder.Entity<Blog>().HasData(
                new Blog { BlogId = 1, Url = "http://blogs.msdn.com/dotnet", Rating = 5 },
                new Blog { BlogId = 2, Url = "http://blogs.msdn.com/visualstudio", Rating = 4 },
                new Blog { BlogId = 3, Url = "http://blogs.msdn.com/webdev", Rating = 3 }
            );
        }
    }
    
    // Entity classes
    public class Blog
    {
        public int BlogId { get; set; }
        
        [Required]
        [MaxLength(200)]
        public string Url { get; set; }
        
        public int Rating { get; set; }
        
        // Navigation properties
        public List<Post> Posts { get; set; } = new List<Post>();
        public Author Author { get; set; }
        public int? AuthorId { get; set; }
    }
    
    public class Post
    {
        public int PostId { get; set; }
        
        [Required]
        [MaxLength(200)]
        public string Title { get; set; }
        
        public string Content { get; set; }
        
        public DateTime PublishedOn { get; set; }
        public bool IsPublished { get; set; }
        
        // Foreign key
        public int BlogId { get; set; }
        
        // Navigation properties
        public Blog Blog { get; set; }
        public List<Tag> Tags { get; set; } = new List<Tag>();
    }
    
    public class Tag
    {
        public int TagId { get; set; }
        
        [Required]
        [MaxLength(50)]
        public string Name { get; set; }
        
        // Navigation property (many-to-many)
        public List<Post> Posts { get; set; } = new List<Post>();
    }
    
    public class Author
    {
        public int AuthorId { get; set; }
        
        [Required]
        [MaxLength(100)]
        public string Name { get; set; }
        
        [Required]
        [EmailAddress]
        public string Email { get; set; }
        
        public string Bio { get; set; }
        
        // Navigation property (one-to-one)
        public Blog Blog { get; set; }
    }
    
    // Repository pattern with EF Core
    public interface IBlogRepository
    {
        Task<Blog> GetBlogByIdAsync(int id);
        Task<List<Blog>> GetAllBlogsAsync();
        Task<List<Blog>> GetBlogsByRatingAsync(int minRating);
        Task AddBlogAsync(Blog blog);
        Task UpdateBlogAsync(Blog blog);
        Task DeleteBlogAsync(int id);
        Task<bool> SaveChangesAsync();
    }
    
    public class BlogRepository : IBlogRepository
    {
        private readonly BloggingContext _context;
        
        public BlogRepository(BloggingContext context)
        {
            _context = context;
        }
        
        public async Task<Blog> GetBlogByIdAsync(int id)
        {
            return await _context.Blogs
                .Include(b => b.Posts)
                .Include(b => b.Author)
                .FirstOrDefaultAsync(b => b.BlogId == id);
        }
        
        public async Task<List<Blog>> GetAllBlogsAsync()
        {
            return await _context.Blogs
                .Include(b => b.Posts)
                .Include(b => b.Author)
                .OrderBy(b => b.Url)
                .ToListAsync();
        }
        
        public async Task<List<Blog>> GetBlogsByRatingAsync(int minRating)
        {
            return await _context.Blogs
                .Where(b => b.Rating >= minRating)
                .Include(b => b.Posts)
                .OrderByDescending(b => b.Rating)
                .ToListAsync();
        }
        
        public async Task AddBlogAsync(Blog blog)
        {
            await _context.Blogs.AddAsync(blog);
        }
        
        public async Task UpdateBlogAsync(Blog blog)
        {
            _context.Blogs.Update(blog);
        }
        
        public async Task DeleteBlogAsync(int id)
        {
            var blog = await GetBlogByIdAsync(id);
            if (blog != null)
            {
                _context.Blogs.Remove(blog);
            }
        }
        
        public async Task<bool> SaveChangesAsync()
        {
            return await _context.SaveChangesAsync() > 0;
        }
    }
    
    // Service layer
    public class BlogService
    {
        private readonly IBlogRepository _blogRepository;
        
        public BlogService(IBlogRepository blogRepository)
        {
            _blogRepository = blogRepository;
        }
        
        public async Task<List<Blog>> GetPopularBlogsAsync(int minRating = 4)
        {
            return await _blogRepository.GetBlogsByRatingAsync(minRating);
        }
        
        public async Task<Blog> CreateBlogAsync(string url, int rating, string authorName, string authorEmail)
        {
            var blog = new Blog
            {
                Url = url,
                Rating = rating,
                Author = new Author
                {
                    Name = authorName,
                    Email = authorEmail
                }
            };
            
            await _blogRepository.AddBlogAsync(blog);
            await _blogRepository.SaveChangesAsync();
            
            return blog;
        }
        
        public async Task<bool> UpdateBlogRatingAsync(int blogId, int newRating)
        {
            var blog = await _blogRepository.GetBlogByIdAsync(blogId);
            if (blog == null)
                return false;
            
            blog.Rating = newRating;
            await _blogRepository.UpdateBlogAsync(blog);
            return await _blogRepository.SaveChangesAsync();
        }
    }
    
    // Usage examples
    class Program
    {
        static async Task Main(string[] args)
        {
            // Setup DI container in real applications
            var optionsBuilder = new DbContextOptionsBuilder<BloggingContext>();
            optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Blogging;Trusted_Connection=True");
            
            using var context = new BloggingContext(optionsBuilder.Options);
            
            // Ensure database is created
            await context.Database.EnsureCreatedAsync();
            
            var repository = new BlogRepository(context);
            var blogService = new BlogService(repository);
            
            // CRUD operations
            Console.WriteLine("=== EF CORE DEMONSTRATION ===\n");
            
            // Create
            var newBlog = await blogService.CreateBlogAsync(
                "https://example.com/blog", 5, "John Doe", "john@example.com");
            Console.WriteLine($"Created blog: {newBlog.Url}");
            
            // Read
            var blogs = await blogService.GetPopularBlogsAsync(4);
            Console.WriteLine("\nPopular blogs:");
            foreach (var blog in blogs)
            {
                Console.WriteLine($" - {blog.Url} (Rating: {blog.Rating})");
            }
            
            // Complex query with LINQ
            var postsWithTags = await context.Posts
                .Where(p => p.PublishedOn > DateTime.Now.AddMonths(-1))
                .Include(p => p.Tags)
                .Include(p => p.Blog)
                .ThenInclude(b => b.Author)
                .OrderByDescending(p => p.PublishedOn)
                .ToListAsync();
            
            Console.WriteLine("\nRecent posts with tags:");
            foreach (var post in postsWithTags.Take(3))
            {
                Console.WriteLine($" - {post.Title} by {post.Blog.Author?.Name}");
                Console.WriteLine($"   Tags: {string.Join(", ", post.Tags.Select(t => t.Name))}");
            }
            
            // Raw SQL queries
            var highRatedBlogs = await context.Blogs
                .FromSqlRaw("SELECT * FROM Blogs WHERE Rating > {0}", 3)
                .Include(b => b.Posts)
                .ToListAsync();
            
            // Transactions
            using var transaction = await context.Database.BeginTransactionAsync();
            try
            {
                // Multiple operations in transaction
                context.Blogs.Add(new Blog { Url = "https://temp.com", Rating = 3 });
                await context.SaveChangesAsync();
                
                await transaction.CommitAsync();
            }
            catch
            {
                await transaction.RollbackAsync();
                throw;
            }
            
            Console.WriteLine("\nEF Core operations completed!");
        }
    }
}

Advanced EF Core and Performance

Advanced Entity Framework Core features include complex queries, performance optimization, change tracking, and working with stored procedures.
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using System.Diagnostics;

namespace AdvancedEFCore
{
    public class AdvancedBloggingContext : DbContext
    {
        public DbSet<Blog> Blogs { get; set; }
        public DbSet<Post> Posts { get; set; }
        public DbSet<Author> Authors { get; set; }
        public DbSet<BlogStats> BlogStats { get; set; }
        
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer(
                @"Server=(localdb)\mssqllocaldb;Database=AdvancedBlogging;Trusted_Connection=True")
                .LogTo(Console.WriteLine, Microsoft.Extensions.Logging.LogLevel.Information)
                .EnableSensitiveDataLogging();
        }
        
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            // Configure owned types (value objects)
            modelBuilder.Entity<Author>().OwnsOne(a => a.Address);
            
            // Configure table-valued functions
            modelBuilder.HasDbFunction(typeof(AdvancedBloggingContext)
                .GetMethod(nameof(GetPopularPosts), new[] { typeof(int) }))
                .HasName("ufn_GetPopularPosts");
            
            // Configure computed columns
            modelBuilder.Entity<Post>()
                .Property(p => p.Slug)
                .HasComputedColumnSql("LOWER(REPLACE(Title, ' ', '-'))", stored: true);
            
            // Configure concurrency tokens
            modelBuilder.Entity<Blog>()
                .Property(b => b.Version)
                .IsRowVersion();
            
            // Configure query filters
            modelBuilder.Entity<Post>()
                .HasQueryFilter(p => p.IsPublished);
        }
        
        // Table-valued function mapping
        public IQueryable<Post> GetPopularPosts(int minLikes) =>
            FromExpression(() => GetPopularPosts(minLikes));
    }
    
    // Entity with owned type
    public class Author
    {
        public int AuthorId { get; set; }
        public string Name { get; set; }
        public string Email { get; set; }
        public Address Address { get; set; }
        public List<Blog> Blogs { get; set; } = new List<Blog>();
    }
    
    // Owned type (value object)
    public class Address
    {
        public string Street { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string ZipCode { get; set; }
        public string Country { get; set; }
    }
    
    // Entity for keyless entity type (view/query)
    [Keyless]
    public class BlogStats
    {
        public int BlogId { get; set; }
        public string BlogUrl { get; set; }
        public int PostCount { get; set; }
        public int TotalLikes { get; set; }
        public DateTime LastPostDate { get; set; }
    }
    
    public class AdvancedBlogService
    {
        private readonly AdvancedBloggingContext _context;
        
        public AdvancedBlogService(AdvancedBloggingContext context)
        {
            _context = context;
        }
        
        // Explicit loading
        public async Task<Blog> LoadBlogWithPostsAsync(int blogId)
        {
            var blog = await _context.Blogs.FindAsync(blogId);
            if (blog != null)
            {
                // Explicitly load related data
                await _context.Entry(blog)
                    .Collection(b => b.Posts)
                    .Query()
                    .Where(p => p.IsPublished)
                    .LoadAsync();
                
                await _context.Entry(blog)
                    .Reference(b => b.Author)
                    .LoadAsync();
            }
            
            return blog;
        }
        
        // Change tracking examples
        public async Task DemonstrateChangeTracking()
        {
            var blog = await _context.Blogs.FirstAsync();
            
            // Original values
            var originalUrl = _context.Entry(blog).OriginalValues["Url"];
            var currentUrl = _context.Entry(blog).CurrentValues["Url"];
            
            Console.WriteLine($"Original URL: {originalUrl}");
            Console.WriteLine($"Current URL: {currentUrl}");
            Console.WriteLine($"State: {_context.Entry(blog).State}");
            Console.WriteLine($"Modified: {_context.Entry(blog).Property(b => b.Url).IsModified}");
            
            // Detect changes
            _context.ChangeTracker.DetectChanges();
            
            // Accept all changes
            _context.ChangeTracker.AcceptAllChanges();
        }
        
        // Bulk operations with EF Core 7.0+
        public async Task BulkUpdateBlogRatingsAsync(int oldRating, int newRating)
        {
            await _context.Blogs
                .Where(b => b.Rating == oldRating)
                .ExecuteUpdateAsync(setters => setters
                    .SetProperty(b => b.Rating, newRating)
                    .SetProperty(b => b.UpdatedAt, DateTime.UtcNow));
        }
        
        public async Task BulkDeleteOldPostsAsync(DateTime cutoffDate)
        {
            await _context.Posts
                .Where(p => p.PublishedOn < cutoffDate && !p.IsPublished)
                .ExecuteDeleteAsync();
        }
        
        // Complex query with multiple includes and filtering
        public async Task<List<Blog>> GetBlogsWithRecentPostsAsync(int days = 30)
        {
            var cutoffDate = DateTime.UtcNow.AddDays(-days);
            
            return await _context.Blogs
                .Include(b => b.Author)
                .Include(b => b.Posts
                    .Where(p => p.PublishedOn >= cutoffDate && p.IsPublished)
                    .OrderByDescending(p => p.PublishedOn)
                    .Take(5))
                .ThenInclude(p => p.Tags)
                .Where(b => b.Posts.Any(p => p.PublishedOn >= cutoffDate))
                .OrderByDescending(b => b.Rating)
                .AsSplitQuery() // Prevents Cartesian explosion
                .ToListAsync();
        }
        
        // Raw SQL with parameters
        public async Task<List<Blog>> SearchBlogsAsync(string searchTerm)
        {
            return await _context.Blogs
                .FromSqlRaw(
                    "SELECT * FROM Blogs WHERE Url LIKE {0} OR BlogId IN (SELECT BlogId FROM Posts WHERE Title LIKE {1})",
                    $"%{searchTerm}%", $"%{searchTerm}%")
                .Include(b => b.Posts)
                .ToListAsync();
        }
        
        // Stored procedure execution
        public async Task<int> UpdateBlogStatisticsAsync(int blogId)
        {
            var result = await _context.Database
                .ExecuteSqlRawAsync("EXEC UpdateBlogStatistics @BlogId = {0}", blogId);
            
            return result;
        }
        
        // Performance optimization: AsNoTracking
        public async Task<List<Blog>> GetBlogsReadOnlyAsync()
        {
            return await _context.Blogs
                .AsNoTracking() // No change tracking - better performance for read-only
                .Include(b => b.Posts)
                .AsNoTrackingWithIdentityResolution() // EF Core 5.0+
                .ToListAsync();
        }
        
        // Global query filters
        public async Task<List<Post>> GetAllPostsIncludingUnpublishedAsync()
        {
            return await _context.Posts
                .IgnoreQueryFilters() // Bypass the IsPublished filter
                .ToListAsync();
        }
        
        // Transaction with savepoints
        public async Task ComplexOperationWithSavepointsAsync()
        {
            using var transaction = await _context.Database.BeginTransactionAsync();
            
            try
            {
                // Operation 1
                _context.Blogs.Add(new Blog { Url = "https://blog1.com", Rating = 4 });
                await _context.SaveChangesAsync();
                
                // Create savepoint
                await transaction.CreateSavepointAsync("AfterBlog1");
                
                // Operation 2 - might fail
                try
                {
                    _context.Blogs.Add(new Blog { Url = null, Rating = 5 }); // This will fail
                    await _context.SaveChangesAsync();
                }
                catch
                {
                    // Rollback to savepoint
                    await transaction.RollbackToSavepointAsync("AfterBlog1");
                }
                
                // Operation 3 - continues after rollback
                _context.Blogs.Add(new Blog { Url = "https://blog3.com", Rating = 3 });
                await _context.SaveChangesAsync();
                
                await transaction.CommitAsync();
            }
            catch
            {
                await transaction.RollbackAsync();
                throw;
            }
        }
        
        // Interceptors (EF Core 5.0+)
        public void DemonstrateInterceptors()
        {
            // In real applications, you'd register these in DbContext configuration
            // optionsBuilder.AddInterceptors(new MyCommandInterceptor(), new MyConnectionInterceptor());
        }
    }
    
    // Performance benchmarking
    public class EFPerformanceBenchmark
    {
        private readonly AdvancedBloggingContext _context;
        
        public EFPerformanceBenchmark(AdvancedBloggingContext context)
        {
            _context = context;
        }
        
        public async Task MeasureQueryPerformanceAsync()
        {
            var stopwatch = Stopwatch.StartNew();
            
            // Inefficient: N+1 query problem
            var blogs = await _context.Blogs.ToListAsync();
            foreach (var blog in blogs)
            {
                var posts = await _context.Posts
                    .Where(p => p.BlogId == blog.BlogId)
                    .ToListAsync(); // This causes N additional queries!
            }
            
            stopwatch.Stop();
            Console.WriteLine($"N+1 queries: {stopwatch.ElapsedMilliseconds}ms");
            
            stopwatch.Restart();
            
            // Efficient: Single query with Include
            var blogsWithPosts = await _context.Blogs
                .Include(b => b.Posts)
                .ToListAsync();
            
            stopwatch.Stop();
            Console.WriteLine($"Single query with Include: {stopwatch.ElapsedMilliseconds}ms");
            
            stopwatch.Restart();
            
            // More efficient: Filtered Include (EF Core 5.0+)
            var blogsWithRecentPosts = await _context.Blogs
                .Include(b => b.Posts.Where(p => p.IsPublished)
                    .OrderByDescending(p => p.PublishedOn)
                    .Take(5))
                .ToListAsync();
            
            stopwatch.Stop();
            Console.WriteLine($"Filtered Include: {stopwatch.ElapsedMilliseconds}ms");
        }
    }
    
    class Program
    {
        static async Task Main(string[] args)
        {
            var optionsBuilder = new DbContextOptionsBuilder<AdvancedBloggingContext>();
            optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=AdvancedBlogging;Trusted_Connection=True");
            
            using var context = new AdvancedBloggingContext(optionsBuilder.Options);
            await context.Database.EnsureCreatedAsync();
            
            var service = new AdvancedBlogService(context);
            var benchmark = new EFPerformanceBenchmark(context);
            
            Console.WriteLine("=== ADVANCED EF CORE FEATURES ===\n");
            
            // Demonstrate complex queries
            var blogs = await service.GetBlogsWithRecentPostsAsync(30);
            Console.WriteLine($"Found {blogs.Count} blogs with recent posts\n");
            
            // Demonstrate performance
            await benchmark.MeasureQueryPerformanceAsync();
            Console.WriteLine();
            
            // Demonstrate change tracking
            await service.DemonstrateChangeTracking();
            Console.WriteLine();
            
            // Demonstrate bulk operations
            await service.BulkUpdateBlogRatingsAsync(3, 4);
            Console.WriteLine("Bulk update completed\n");
            
            Console.WriteLine("Advanced EF Core features demonstrated!");
        }
    }
}

💻 Hands-On Practice Exercises

Beginner Level

  • 1Create a console calculator that handles basic arithmetic operations
  • 2Build a student grade management system with classes and objects
  • 3Implement a simple bank account system with deposit/withdrawal functionality
  • 4Create a temperature converter between Celsius and Fahrenheit
  • 5Build a number guessing game with user input validation

Intermediate Level

  • 1Develop a RESTful Web API for a todo list application
  • 2Create a LINQ-based data analysis tool for sales data
  • 3Build an ASP.NET Core MVC application for product catalog management
  • 4Implement a file processing system with async/await operations
  • 5Create a dependency injection container and demonstrate its usage

Advanced Level

  • 1Build a full-stack e-commerce application with ASP.NET Core and Entity Framework
  • 2Create a real-time chat application using SignalR
  • 3Implement a microservices architecture with API Gateway pattern
  • 4Build a machine learning model integration using ML.NET
  • 5Create a high-performance data processing pipeline with parallel programming

🚀 Popular C# Frameworks & Technologies

ASP.NET Core

Cross-platform framework for building modern cloud-based web applications

  • MVC Pattern
  • Razor Pages
  • Web API
  • Dependency Injection
// Minimal API example
var app = WebApplication.Create(args);

app.MapGet("/", () => "Hello World!");
app.MapGet("/users/{id}", (int id) => $"User ID: {id}");

app.Run();

Entity Framework Core

Modern object-database mapper for .NET with LINQ support

  • Code First
  • Migrations
  • LINQ Queries
  • Change Tracking
// EF Core DbContext
public class AppDbContext : DbContext
{
    public DbSet<User> Users { get; set; }
    
    protected override void OnConfiguring(
        DbContextOptionsBuilder options)
        => options.UseSqlServer(connectionString);
}

Blazor

Framework for building interactive web UIs using C# instead of JavaScript

  • WebAssembly
  • Server-side
  • Components
  • SignalR
// Blazor component
<button @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;
    
    private void IncrementCount()
    {
        currentCount++;
    }
}

Xamarin/.NET MAUI

Framework for building cross-platform mobile and desktop apps

  • iOS & Android
  • Windows & macOS
  • Single Project
  • Native UI
// MAUI ContentPage
<ContentPage>
    <VerticalStackLayout>
        <Label Text="Welcome to .NET MAUI!" />
        <Button Text="Click me" Clicked="OnCounterClicked" />
    </VerticalStackLayout>
</ContentPage>

🎯 C# Career Paths

Backend Developer

ASP.NET Core, Web APIs, Microservices, Cloud

Full-Stack Developer

C# + JavaScript/TypeScript, Blazor, React/Angular

Game Developer

Unity Engine, Game Logic, Performance Optimization

Continue Your C# Journey!

You've now explored the comprehensive landscape of C# programming, from basic syntax to advanced enterprise development patterns. C# continues to evolve with each version, bringing modern features and performance improvements.

The .NET ecosystem offers endless possibilities - explore cloud development with Azure, build cross-platform apps with MAUI, create games with Unity, or dive into machine learning with ML.NET.

Happy Coding! ⚡

This comprehensive guide covers C# from absolute fundamentals to advanced .NET development concepts.

Designed for clarity and depth - perfect for beginners and professional developers alike.

© 2025 C# Mastery Guide | Keep Learning, Keep Building!