C# & .NET

C# & .NET Platform Architecture

A modern, type-safe, object-oriented language paired with a high-performance cross-platform runtime engine. Built for enterprise software, web microservices, game engines, and cloud-native computing.

00 / Evolution

History & Origin of C# and .NET

C# was unveiled in 2000 by Microsoft, designed under the leadership of Anders Hejlsberg (creator of Turbo Pascal and principal architect of Delphi). Designed as a key language for the new .NET Framework, C# aimed to combine the high productivity of Visual Basic with the raw structural power of C++.

C# & .NET Major Version Timeline

C# 1.0 / 2.0 2002-2005 Generics C# 3.0 2007 LINQ & Lambdas C# 5.0 2012 Async / Await .NET Core 1.0 2016 Cross-Platform Unified .NET 8/9 2023+ Records & Native AOT

Milestones of C# Evolution

C# 1.0 - 2.0 (2002 - 2005)

Introduced managed code on Windows, followed by compile-time type safety via Generics, anonymous methods, and nullable value types.

C# 3.0 (2007) - LINQ Revolution

Brought functional features: LINQ, Lambda expressions, extension methods, and anonymous types.

C# 5.0 (2012) - Async / Await

Transformed concurrent programming by introducing native compiler-generated async / await state machines.

.NET Core (2016) & Unified .NET (2020+)

Transitioned to open-source, cross-platform architecture (Linux, macOS, Windows) with Records, Pattern Matching, Minimal APIs, and Native AOT compilation.

01 / Setup

Installation & .NET SDK Setup

To develop C# applications, install the official cross-platform .NET SDK (Software Development Kit). The SDK includes the Roslyn C# compiler, the CLR runtime execution engine, and the dotnet Command-Line Interface (CLI).

Visual Studio 2022

Full-featured IDE for Windows with integrated debugging, profiler, and enterprise tools.

VS Code + C# Dev Kit

Lightweight cross-platform editor with IntelliSense, Solution Explorer, and unit test runner.

JetBrains Rider

Cross-platform .NET IDE offering deep code refactoring and performance profiling.

# 1. Verify installed .NET SDK version
dotnet --info

# 2. Create a new Console Application
dotnet new console -o UndrstandingApp

# 3. Change directory and run the application
cd UndrstandingApp
dotnet run
02 / Syntax & Anatomy

Anatomy of a C# Program: using, namespace, and class

Every C# application is constructed from fundamental building blocks: using directives to import standard libraries, namespace declarations to logically group types, and class blueprints containing methods, fields, and constructors.

1. using Directives

Imports existing namespaces (e.g. using System;) so you can use types like Console or List<T> without writing full qualifiers like System.Console.

Modern C# 10+: Supports global using and SDK-wide Implicit Usings.
2. namespace Declaration

Provides a logical container for your classes, preventing class name collisions across large projects and external packages.

File-Scoped Syntax: namespace UndrstandingApp; (omits extra indentation braces).
3. class Blueprint

The fundamental Object-Oriented building block encapsulating state (fields/properties) and behavior (methods) with access modifiers like public or private.

Example: public class Program { ... }
4. Main() Method / Entry Point

The mandatory runtime entry point invoked by the CLR when the executable starts up. static allows execution without instantiating the class first.

Signature: static void Main(string[] args)

Modern Top-Level Syntax (C# 9+)

// Program.cs (Top-Level Statements)
// Roslyn auto-wraps namespace & Main()

using System;

Console.WriteLine("Hello, Undrstanding!");
GreetUser("Developer");

// Local function declaration
void GreetUser(string name)
{
    Console.WriteLine($"Welcome, {name}!");
}

Traditional Program Structure

using System; // 1. Import

namespace UndrstandingApp; // 2. Scope

public class Program // 3. Class
{
    public static void Main(string[] args) // 4. Entry
    {
        Console.WriteLine("Hello, World!");
        GreetUser("Developer");
    }

    static void GreetUser(string name) =>
        Console.WriteLine($"Welcome, {name}!");
}
03 / Variables

Variable Declarations, Data Types & Constants

C# is a strongly-typed language. You can declare variables explicitly with data types or implicitly using the var keyword (where the compiler infers the exact type at compile time).

Value Types (Stack) vs Reference Types (Managed Heap)

Thread Stack int age = 25 (Value) ref ptr: 0x7FFF1A40 Managed Heap UserProfile Object Id = "USR-99" Email = "student@..."
// Explicit Variable Declarations
int age = 25;
double score = 98.5;
decimal price = 19.99m; // High precision decimal for financial data
bool isActive = true;
string platformName = "Undrstanding";

// Implicit Typing with 'var' (Type inferred as string at compile time)
var userEmail = "student@undrstanding.com";

// Compile-Time Constant vs Readonly Field
const double Pi = 3.14159265;
readonly DateTime ServerStartTime = DateTime.UtcNow;

Console.WriteLine($"User: {userEmail} | Score: {score}");
Console.WriteLine($"Price: ${price} | Active: {isActive}");
04 / Control Flow

Conditionals, Switch Expressions & Iteration Loops

C# supports standard conditional branching (if, else if, else), pattern-matching switch expressions, and iteration loops (foreach, for, while, do-while).

// 1. Iteration with 'foreach' over array
string[] topics = { "CLR", "LINQ", "Async", "Span" };

foreach (var topic in topics)
{
    Console.WriteLine($"Studying: {topic}");
}

// 2. Pattern Matching Switch Expression
int statusCode = 200;
string message = statusCode switch
{
    200 => "Success / OK",
    404 => "Resource Not Found",
    500 => "Internal Server Error",
    _   => "Unknown HTTP Status"
};
Console.WriteLine($"Status {statusCode}: {message}");
05 / Architecture

The Common Language Runtime (CLR) & Execution Engine

C# source code compiles into Common Intermediate Language (CIL/MSIL) bytecode rather than raw machine instructions. At execution time, the CLR's Just-In-Time (JIT) compiler translates bytecode into optimized native CPU instructions while managing type safety and automatic memory reclamation.

CLR Garbage Collector Generations Architecture

Gen 0 Short-lived Frequent Collection Gen 1 Buffer Layer Survivor Pool Gen 2 Long-lived Singletons/Statics LOH (>85KB) Large Objects No Copy Compaction
// C# Compilation & Execution Pipeline
C# Source (.cs)Roslyn CompilerCIL Bytecode (.dll)CLR JITNative Machine Code
06 / Memory & Type System

Value Types, Reference Types & Boxing

C# segregates memory allocation into Value Types (primitives, structs on the stack) and Reference Types (classes, arrays, delegates on the managed heap). Boxing converts a value type to an object reference, incurring a heap allocation performance penalty.

// 1. Immutable Record Declaration (C# 9+)
public record UserProfile(string Id, string Email, DateTime CreatedAt);

// 2. Pattern Matching with Switch Expressions
public static decimal CalculateDiscount(object customer) => customer switch
{
    UserProfile { CreatedAt: var date } when date.Year < 2020 => 0.20m,
    UserProfile _ => 0.05m,
    null => 0.0m,
    _ => throw new ArgumentException("Unknown customer type")
};

// 3. Nullable Reference Types & Coalescing Operator
string? input = null;
string displayName = input?.Trim() ?? "Anonymous Student";
Console.WriteLine($"Display Name: {displayName}");
07 / High Performance

Span<T>, Memory<T> & Zero-Allocation Slicing

Span<T> is a stack-only ref struct representing a contiguous region of arbitrary memory (managed heap arrays, stack memory via stackalloc, or native unmanaged pointers) without allocation overhead.

Span<char> Contiguous Memory Slice (Zero Heap Allocation)

Underlying Contiguous Memory Buffer (char[]) A [0] u [1] t [2] h [3] B [4] e [5] a [6] r [7] e [8] r [9] ... [10] ReadOnlySpan<char> Slice Window: "Bearer" (Pointer + Length: 6)
// Zero-Allocation String Slicing with ReadOnlySpan<char>
string rawHeader = "Authorization: Bearer eyJhbGciOiJIUzI1Ni...";
ReadOnlySpan<char> span = rawHeader.AsSpan();

// Slice without allocating a new string object
ReadOnlySpan<char> token = span.Slice(15, 6);
Console.WriteLine($"Sliced Token: {token.ToString()}");
Console.WriteLine($"Span Length: {token.Length} chars");
08 / Object Orientation

Generics, Variance & Events

C# provides compile-time type safety with Generics and supports Generic Variance: Covariance (out T) for output types and Contravariance (in T) for input parameter types.

// Generic Repository Interface with Type Constraints & Covariance
public interface IReadOnlyRepository<out TEntity, in TId> 
    where TEntity : class
    where TId : notnull
{
    Task<TEntity?> GetByIdAsync(TId id, CancellationToken ct = default);
}

// Strongly-Typed Event Handler Delegate
public class DataEngine
{
    public event Action<string>? OnProcessed;

    public void Execute()
    {
        OnProcessed?.Invoke("Data pipeline processing finished successfully.");
    }
}

var engine = new DataEngine();
engine.OnProcessed += msg => Console.WriteLine($"[EVENT] {msg}");
engine.Execute();
09 / Functional Querying

LINQ Architecture: IEnumerable vs IQueryable

LINQ standardizes querying over collections. IEnumerable<T> operates on in-memory collections using delegates, whereas IQueryable<T> compiles queries into Expression Trees for remote SQL database translation.

var numbers = new List<int> { 1, 2, 3, 4, 5 };

// Query defined (Deferred Execution - Not processed yet)
var query = numbers
    .Where(n => n % 2 == 0)
    .Select(n => n * 10);

numbers.Add(6); // Mutate list after query definition

// Execution triggered HERE during enumeration
foreach (var item in query)
{
    Console.WriteLine(item);
}
10 / Asynchrony

Async State Machines & Thread Pool Context

The Roslyn compiler transforms async methods into state machine structs behind the scenes. Using ConfigureAwait(false) suppresses capturing the current SynchronizationContext, yielding superior throughput in server applications.

public async Task<string> DownloadPayloadAsync(string url, CancellationToken ct)
{
    using var client = new HttpClient();
    
    // Non-blocking asynchronous network request avoiding context capture
    Console.WriteLine($"[ASYNC] Dispatching request to {url}...");
    var response = await client.GetAsync(url, ct).ConfigureAwait(false);
    return await response.Content.ReadAsStringAsync(ct).ConfigureAwait(false);
}
11 / Ecosystem

ASP.NET Core & Dependency Injection Lifetimes

Unified .NET provides built-in IoC Dependency Injection with three primary service lifetimes:

Transient

Created every time requested from container.

Scoped

Created once per HTTP Request connection scope.

Singleton

Single instance shared across entire app lifetime.

12 / Appendix

C# & .NET Glossary

CLR (Common Language Runtime)

Execution engine for .NET applications providing GC, type safety, and JIT compilation.

CIL / MSIL

Common Intermediate Language bytecode emitted by C# Roslyn compiler.

Span<T>

Stack-allocated ref struct providing contiguous zero-allocation memory slicing.

LINQ

Language Integrated Query for operating on data sources in functional syntax.

Large Object Heap (LOH)

Heap partition for objects larger than 85,000 bytes, avoiding frequent GC compaction copies.

Native AOT

Ahead-Of-Time compilation directly generating standalone native binary executables without JIT.

13 / Evaluation

Knowledge Check (10 Assessment Questions)

Verify your understanding of C# syntax, SDK installation, CLR runtime mechanics, Span memory slicing, LINQ, and ASP.NET Core architecture. Pass all 10 questions to earn your certificate.