Complete Reference · Free Download

C# & .NET Core
Quick Guide

Every essential C# and .NET Core concept in one place — syntax, OOP, LINQ, async/await, generics, dependency injection, Entity Framework, testing and more.

Browse Cheat Sheet ↓
12+Topics Covered
200+Code Examples
8 pagesPDF Download
FreeAlways
Fundamentals

Variables, Types & Syntax

C# is a statically-typed language. Understand value types, reference types, nullable types and modern expression syntax.

📌
Variables & Data Types
Value types, reference types, implicit typing and nullable types.
csharp
// Value types
int    age     = 30;
double pi      = 3.14159;
float  temp    = 36.6f;
decimal price = 19.99m;
bool   active  = true;
char   grade   = 'A';

// Reference types
string  name = "Alice";
object  obj  = new Object();

// Implicit typing
var count = 10;          // int
var msg   = "hello";     // string

// Nullable types
int?    nullInt = null;
string? nullStr = null;

// Null-coalescing operators
var val  = nullInt ?? 0;
nullStr ??= "default";
🔀
Control Flow
if/else, switch expressions, pattern matching, loops.
csharp
// Switch expression (C# 8+)
var result = score switch {
    >= 90 => "A",
    >= 80 => "B",
    >= 70 => "C",
    _      => "F"
};

// Pattern matching
if (obj is string s && s.Length > 5)
    Console.WriteLine(s.ToUpper());

// foreach loop
foreach (var item in items)
    Console.WriteLine(item);

// for / while / do-while
for (int i=0; i<10; i++) { }
while (condition) { }
do { } while (condition);
📝
Strings & Interpolation
String operations, interpolation, verbatim and raw literals.
csharp
// String interpolation
var msg = $"Hello, {name}! Age: {age}";

// Verbatim string (raw path)
var path = @"C:\Users\Alice\docs";

// Raw string literal (C# 11+)
var json = """
  { "name": "Alice" }
""";

// Common methods
name.ToUpper();
name.ToLower();
name.Trim();
name.Contains("Alice");
name.Replace("a", "@");
name.Split(',');
string.Join(", ", items);

// StringBuilder (mutable)
var sb = new StringBuilder();
sb.Append("Hello");
sb.AppendLine(" World");
🗂️
C# Type System Quick Reference
Value types, sizes and their .NET equivalents.
Alias .NET Type Size Range / Notes
int System.Int32 32-bit −2,147,483,648 to 2,147,483,647
long System.Int64 64-bit ±9.2 × 10¹⁸
double System.Double 64-bit ~15-17 significant digits
decimal System.Decimal 128-bit 28-29 digits, ideal for money
bool System.Boolean 8-bit true / false
char System.Char 16-bit Unicode character
string System.String ref type Immutable sequence of chars
object System.Object ref type Root of all C# types
Object-Oriented Programming

Classes, Interfaces & OOP

Master classes, records, interfaces, inheritance, polymorphism, encapsulation and access modifiers in C#.

🏛️
Classes & Records
Class anatomy, auto-properties, constructors and records.
csharp
public class Person {
  // Auto-properties
  public string Name  { get; set; } = "";
  public int    Age   { get; init; }
  public string Email { get; private set; } = "";

  // Primary constructor (C# 12)
  public Person(string name, int age) {
    Name = name; Age = age;
  }

  // Method
  public string Greet() =>
    $"Hi, I'm {Name}, aged {Age}";
}

// Record — immutable by default
public record Product(
  string Name,
  decimal Price
);

// With-expression (non-destructive)
var p1 = new Product("Pen", 1.99m);
var p2 = p1 with { Price = 2.49m };
🔌
Interfaces & Inheritance
Interface contracts, abstract classes and sealed types.
csharp
// Interface
public interface IAnimal {
  string Name { get; }
  void Speak();
  // Default impl (C# 8+)
  string Describe() => $"I am {Name}";
}

// Abstract base class
public abstract class Animal : IAnimal {
  public string Name { get; }
  protected Animal(string name) => Name=name;
  public abstract void Speak();
}

// Concrete class
public sealed class Dog : Animal {
  public Dog(string name) : base(name) {}
  public override void Speak() =>
    Console.WriteLine("Woof!");
}

// Polymorphism
IAnimal a = new Dog("Rex");
a.Speak(); // Woof!
🎭
Access Modifiers & Members
Visibility, static members, enums and structs.
Modifier Visibility
public Anywhere
private Same class only
protected Class + derived classes
internal Same assembly
protected internal Assembly or derived
private protected Same assembly + derived
csharp
// Enum
public enum Status {
  Active, Inactive, Pending
}
Status s = Status.Active;

// Struct (value type)
public struct Point {
  public int X, Y;
}

// Static class
public static class MathHelper {
  public static int Square(int n) => n*n;
}
Data Structures

Collections & Arrays

Arrays, Lists, Dictionaries, HashSets, Stacks, Queues and immutable collections from the .NET BCL.

📋
Arrays & List<T>
Declare arrays and use the most common generic list type.
csharp
// Array
int[] nums = { 1, 2, 3, 4, 5 };
int[] arr  = new int[10];
var   len  = nums.Length;

// List<T>
var list = new List<string> {
  "apple", "banana"
};
list.Add("cherry");
list.Remove("banana");
list.Contains("apple");  // true
list.Count;
list.Sort();
list.Reverse();

// Collection expressions (C# 12)
List<int> nums2 = [1, 2, 3];
int[]       arr2 = [4, 5, 6];
🗺️
Dictionary & HashSet
Key-value stores and unique element collections.
csharp
// Dictionary<TKey,TVal>
var dict = new
  Dictionary<string,int> {
    { "Alice", 30 },
    { "Bob",   25 }
};

dict["Charlie"] = 28;     // add/update
dict.TryGetValue("Alice",
  out int age);              // safe get
dict.ContainsKey("Bob");  // true
dict.Remove("Bob");

// Iterate
foreach (var (k,v) in dict)
  Console.WriteLine($"{k}={v}");

// HashSet<T>
var set = new HashSet<int>
  { 1, 2, 3 };
set.Add(4);
set.UnionWith(new[] {3,4,5});
set.IntersectWith(new[] {2,3});
📦
Queue, Stack & Span
FIFO/LIFO structures and high-performance Span<T>.
csharp
// Queue (FIFO)
var q = new Queue<string>();
q.Enqueue("first");
q.Enqueue("second");
var item = q.Dequeue();  // "first"
q.Peek();               // "second"

// Stack (LIFO)
var stk = new Stack<int>();
stk.Push(1);
stk.Push(2);
var top = stk.Pop();     // 2

// Span<T> — zero-alloc slice
int[] data = [1,2,3,4,5];
Span<int> slice = data.AsSpan(1,3);
// [2,3,4] — no allocation
Language Integrated Query

LINQ

Query any IEnumerable<T> with method syntax or query expressions. Deferred execution and lazy evaluation explained.

🔍
Method Syntax
Fluent LINQ method chaining — the most common approach.
csharp
var nums = new[] { 3,1,4,1,5,9,2 };

// Filter + sort + project
var result = nums
  .Where(n => n > 3)
  .OrderBy(n => n)
  .Select(n => n * 2)
  .ToList();        // [8,10,18]

// Aggregates
nums.Sum();         // 25
nums.Average();     // 3.57
nums.Min();  nums.Max();
nums.Count(n => n > 3); // 3

// First / Single / Any / All
nums.First(n => n>4);
nums.FirstOrDefault(n => n>10);
nums.Any(n => n>8);
nums.All(n => n>0);
🎛️
Grouping, Joining & Projection
GroupBy, Join, SelectMany and anonymous types.
csharp
// GroupBy
var grouped = people
  .GroupBy(p => p.Department)
  .Select(g => new {
    g.Key,
    Count = g.Count(),
    AvgAge = g.Average(p=>p.Age)
  });

// Join
var joined = orders
  .Join(customers,
    o => o.CustomerId,
    c => c.Id,
    (o,c) => new {
      o.Total,
      c.Name
    });

// SelectMany (flatten)
var tags = posts
  .SelectMany(p => p.Tags)
  .Distinct();

// Distinct / Skip / Take
nums.Distinct();
nums.Skip(2).Take(3);
Concurrency

Async / Await & Tasks

Write non-blocking code with async/await, Task, Task<T>, cancellation tokens and parallel operations.

async / await Basics
Async method signatures, await expressions and return types.
csharp
// async method returning Task<T>
public async Task<string> FetchDataAsync(
    string url) {
  using var http = new HttpClient();
  return await http.GetStringAsync(url);
}

// void-returning async
public async Task SaveAsync(Data d) {
  await _repo.SaveAsync(d);
  await _cache.InvalidateAsync();
}

// ValueTask (alloc-free)
public async ValueTask<int> GetAsync()
  => await _source.ReadAsync();

// ConfigureAwait (avoid deadlock)
await task.ConfigureAwait(false);
🔗
Task Composition
WhenAll, WhenAny, parallel and concurrent patterns.
csharp
// Run multiple tasks in parallel
var t1 = FetchAsync("url1");
var t2 = FetchAsync("url2");
var (r1,r2) = await (t1, t2);

// WhenAll — wait for all
var results = await
  Task.WhenAll(t1, t2);

// WhenAny — first completed
var winner = await
  Task.WhenAny(t1, t2);

// Task.Run — background thread
var res = await Task.Run(() =>
  HeavyComputation());

// Parallel.ForEachAsync (NET 6+)
await Parallel.ForEachAsync(
  items, async (item, ct) => {
    await ProcessAsync(item);
  });
🚫
Cancellation & IAsyncEnumerable
CancellationToken patterns and async streams.
csharp
// CancellationToken
public async Task DoWorkAsync(
  CancellationToken ct) {
  await _service.RunAsync(ct);
}

var cts = new CancellationTokenSource();
cts.CancelAfter(5000); // 5s timeout
await DoWorkAsync(cts.Token);

// IAsyncEnumerable (async stream)
public async IAsyncEnumerable<int>
  GenerateAsync() {
  for (int i=0; i<10; i++) {
    await Task.Delay(100);
    yield return i;
  }
}
await foreach (var n in GenerateAsync())
  Console.WriteLine(n);
Type Safety

Generics & Delegates

Write reusable, type-safe code with generic classes, methods, constraints and built-in delegate types.

🧬
Generic Classes & Methods
Type parameters, constraints (where) and covariance.
csharp
// Generic class
public class Repository<T>
  where T : IEntity, new() {
  private List<T> _store = [];
  public void Add(T item) =>
    _store.Add(item);
  public IEnumerable<T> GetAll() => _store;
}

// Generic method
public static T Max<T>(T a, T b)
  where T : IComparable<T>
  => a.CompareTo(b) >= 0 ? a : b;

// Common constraints
// where T : class    — reference type
// where T : struct   — value type
// where T : new()    — has parameterless ctor
// where T : IFoo     — implements interface
// where T : notnull  — non-nullable
🎯
Delegates, Func & Action
Lambda expressions, built-in delegate types and events.
csharp
// Func<TIn, TOut>
Func<int,int,int> add = (a,b) => a+b;
add(3,4); // 7

// Action<T> — returns void
Action<string> print =
  msg => Console.WriteLine(msg);

// Predicate<T> — returns bool
Predicate<int> isEven = n => n%2==0;

// Events
public event EventHandler<string>? OnSaved;
// raise
OnSaved?.Invoke(this, "Saved!");
// subscribe
svc.OnSaved += (s,e) =>
  Console.WriteLine(e);

// Expression trees
Expression<Func<int,bool>> expr
  = x => x > 5;
Web & Runtime

.NET Core & ASP.NET Core

Build APIs, minimal APIs and web apps with ASP.NET Core. Configure middleware, routing, filters and responses.

⚙️
Minimal API (NET 6+)
Zero-ceremony REST endpoints with top-level statements.
csharp
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddScoped<IProductService,
  ProductService>();

var app = builder.Build();
app.UseHttpsRedirection();

// GET endpoint
app.MapGet("/products",
  async (IProductService svc) =>
    Results.Ok(await svc.GetAllAsync()));

// POST endpoint
app.MapPost("/products",
  async (Product p, IProductService svc) => {
    await svc.CreateAsync(p);
    return Results.Created(
      $"/products/{p.Id}", p);
  });

app.Run();
🎮
MVC Controller
ApiController base, routing attributes and action results.
csharp
[ApiController]
[Route("api/[controller]")]
public class ProductsController
  : ControllerBase {

  private readonly IProductService _svc;
  public ProductsController(
    IProductService svc) => _svc=svc;

  [HttpGet]
  public async Task<IActionResult> GetAll()
    => Ok(await _svc.GetAllAsync());

  [HttpGet("{id:int}")]
  public async Task<IActionResult>
    GetById(int id) {
    var p = await _svc.GetAsync(id);
    return p is null ? NotFound():Ok(p);
  }

  [HttpPost]
  public async Task<IActionResult>
    Create(Product p) {
    await _svc.CreateAsync(p);
    return CreatedAtAction(
      nameof(GetById),
      new { p.Id }, p);
  }
}
🔧
Middleware & Configuration
Pipeline middleware, appsettings.json and IConfiguration.
csharp
// Custom middleware
app.Use(async (ctx, next) => {
  // before
  await next();
  // after
});

// Configuration binding
var conn = builder.Configuration
  .GetConnectionString("Default");

// Strongly-typed options
builder.Services
  .Configure<JwtOptions>(
    builder.Configuration
      .GetSection("Jwt"));

// Exception handling middleware
app.UseExceptionHandler("/error");

// Common pipeline
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
IoC Container

Dependency Injection

Register services with the built-in IoC container. Understand lifetime scopes, constructor injection and IServiceProvider.

💉
Service Registration
AddTransient, AddScoped and AddSingleton explained.
csharp
var services = builder.Services;

// Transient — new instance each time
services.AddTransient<
  IEmailService, SmtpEmailService>();

// Scoped — one per HTTP request
services.AddScoped<
  IProductRepo, EfProductRepo>();

// Singleton — one for app lifetime
services.AddSingleton<
  ICacheService, MemoryCacheService>();

// Register with factory
services.AddScoped<IDbContext>(sp =>
  new AppDbContext(
    sp.GetRequiredService<DbOptions>()));

// Register by implementation type
services.AddScoped<MyService>();

// Keyed services (NET 8+)
services.AddKeyedScoped<IParser,
  JsonParser>("json");
🏗️
Lifetimes & Constructor Injection
When to use each lifetime and how to inject dependencies.
Lifetime When Resolved Best For
Transient Every injection Lightweight, stateless services
Scoped Per request DB context, unit of work
Singleton App start, once Config, cache, HTTP client
csharp
// Constructor injection
public class OrderService {
  private readonly IProductRepo _repo;
  private readonly IEmailService _email;
  private readonly ILogger<OrderService> _log;

  public OrderService(
    IProductRepo repo,
    IEmailService email,
    ILogger<OrderService> log) {
    _repo=repo; _email=email; _log=log;
  }
}
Data Access

Entity Framework Core

Map C# classes to database tables. Perform CRUD operations, migrations, eager/lazy loading and raw SQL queries.

🗄️
DbContext & Entities
Define the database context and entity configuration.
csharp
// Entity
public class Product {
  public int     Id       { get; set; }
  public string  Name     { get; set; } = "";
  public decimal Price    { get; set; }
  public int     CategoryId{ get; set; }
  public virtual Category? Category{ get; set; }
}

// DbContext
public class AppDbContext : DbContext {
  public DbSet<Product>  Products   { get; set; }
  public DbSet<Category> Categories { get; set; }

  protected override void
    OnModelCreating(ModelBuilder mb) {
    mb.Entity<Product>()
      .Property(p=>p.Price)
      .HasPrecision(18,2);
  }
}
📝
CRUD Operations
Create, read, update and delete with EF Core async APIs.
csharp
// Create
_ctx.Products.Add(new Product{
  Name="Pen", Price=1.99m
});
await _ctx.SaveChangesAsync();

// Read (LINQ on DbSet)
var all = await _ctx.Products
  .AsNoTracking()
  .ToListAsync();

var p = await _ctx.Products
  .Include(x=>x.Category)
  .FirstOrDefaultAsync(x=>x.Id==1);

// Update
p!.Price = 2.49m;
await _ctx.SaveChangesAsync();

// Delete
_ctx.Products.Remove(p!);
await _ctx.SaveChangesAsync();

// Bulk delete (NET 7+)
await _ctx.Products
  .Where(p=>p.Price<1m)
  .ExecuteDeleteAsync();
🔄
Migrations CLI
Create, apply and revert EF Core database migrations.
bash
# Add a migration
dotnet ef migrations add InitialCreate

# Apply migrations to DB
dotnet ef database update

# Revert to previous migration
dotnet ef database update PreviousMigration

# Remove last migration (not applied)
dotnet ef migrations remove

# Generate SQL script
dotnet ef migrations script

# List migrations
dotnet ef migrations list

# Drop database
dotnet ef database drop --force
Design Patterns

Common .NET Patterns

Repository, CQRS, Options, Result and exception handling patterns commonly used in production .NET applications.

🎯
Exception Handling & Result Pattern
try/catch/finally, custom exceptions and the Result<T> pattern.
csharp
// try / catch / finally
try {
  await RiskyOperationAsync();
} catch (HttpRequestException ex)
  when (ex.StatusCode == 404) {
  _log.LogWarning("Not found");
} catch (Exception ex) {
  _log.LogError(ex, "Failed");
  throw;
} finally {
  Cleanup();
}

// Custom exception
public class NotFoundException
  : Exception {
  public NotFoundException(string msg)
    : base(msg) {}
}

// Result pattern
public record Result<T>(
  T? Value,
  bool IsSuccess,
  string? Error
) {
  public static Result<T> Ok(T v) =>
    new(v, true, null);
  public static Result<T> Fail(string e) =>
    new(default, false, e);
}
🔩
Extension Methods & Utilities
Add methods to existing types without inheritance.
csharp
// Extension methods
public static class StringExtensions {
  public static bool IsNullOrEmpty(
    this string? s) =>
    string.IsNullOrEmpty(s);

  public static string Truncate(
    this string s, int max) =>
    s.Length <= max
      ? s : s[..max] + "…";
}

// Usage
"hello world".Truncate(5); // "hello…"

// Pattern matching (advanced)
var desc = shape switch {
  Circle { Radius: > 10 } => "big circle",
  Circle c => $"circle r={c.Radius}",
  Rectangle r => $"{r.W}x{r.H}",
  null => "no shape",
  _    => "unknown"
};
Quality Assurance

Testing with xUnit & Moq

Write unit tests with xUnit, mock dependencies with Moq and build integration tests with WebApplicationFactory.

🧪
xUnit Tests
Facts, theories, arrange/act/assert and test fixtures.
csharp
public class ProductServiceTests {

  [Fact]
  public void GetPrice_Returns_Correct() {
    // Arrange
    var svc = new ProductService();
    // Act
    var price = svc.GetPrice(1);
    // Assert
    Assert.Equal(9.99m, price);
  }

  [Theory]
  [InlineData(1, true)]
  [InlineData(0, false)]
  public void IsValid_Works(
    int id, bool expected) {
    var svc = new ProductService();
    Assert.Equal(expected,
      svc.IsValid(id));
  }

  [Fact]
  public async Task Create_Throws_When_Null()
    => await Assert.ThrowsAsync<
      ArgumentNullException>(
      () => _svc.CreateAsync(null!));
}
🎭
Mocking with Moq
Mock interfaces, setup behaviours and verify calls.
csharp
var mockRepo = new Mock<IProductRepo>();

// Setup return value
mockRepo
  .Setup(r => r.GetAsync(1))
  .ReturnsAsync(new Product{
    Id=1, Name="Pen"
  });

// Setup exception
mockRepo
  .Setup(r => r.GetAsync(99))
  .ThrowsAsync(new NotFoundException("x"));

// Inject mock into service
var svc = new
  ProductService(mockRepo.Object);

// Verify call was made
mockRepo.Verify(
  r => r.SaveAsync(It.IsAny<Product>()),
  Times.Once());
🌐
Integration Testing
WebApplicationFactory for in-process HTTP integration tests.
csharp
public class ApiTests :
  IClassFixture<WebApplicationFactory<Program>> {

  private readonly HttpClient _client;

  public ApiTests(
    WebApplicationFactory<Program> factory)
    => _client = factory
        .WithWebHostBuilder(b => {
          b.ConfigureServices(s =>
            s.AddSingleton(
              new Mock<IProductRepo>().Object));
        })
        .CreateClient();

  [Fact]
  public async Task
    GetProducts_Returns_200() {
    var resp = await _client
      .GetAsync("/api/products");
    resp.EnsureSuccessStatusCode();
  }
}
Modern C#

Advanced & Modern C# Features

Spans, Source Generators, primary constructors (C# 12), required members and global usings.

🚀
C# 10–12 Features
Top-level statements, file-scoped namespaces, required members.
csharp
// File-scoped namespace (C# 10)
namespace MyApp.Services;

// Global using (C# 10)
global using System.Text.Json;

// Required members (C# 11)
public class Config {
  public required string ApiKey { get; init; }
}
var cfg = new Config{ ApiKey="abc" };

// Primary constructors (C# 12)
public class OrderService(
  IOrderRepo repo,
  ILogger<OrderService> log) {
  public async Task ProcessAsync(int id) {
    var o = await repo.GetAsync(id);
    log.LogInformation("Processing {id}",id);
  }
}
📊
.NET CLI Reference
Essential dotnet CLI commands for building and running projects.
bash
# Create new project
dotnet new webapi -n MyApi
dotnet new console -n MyApp
dotnet new classlib

# Build & run
dotnet build
dotnet run
dotnet watch run      # hot reload

# Package management
dotnet add package Newtonsoft.Json
dotnet remove package Newtonsoft.Json
dotnet list package

# Testing
dotnet test
dotnet test --logger "console;verbosity=normal"

# Publish
dotnet publish -c Release -o ./publish

# Self-contained executable
dotnet publish -r linux-x64 \
  --self-contained true
🔐
SOLID Quick Reference
Five principles for clean, maintainable OOP design.
  • S — SRPSingle Responsibility: each class has one reason to change
  • O — OCPOpen/Closed: open for extension, closed for modification
  • L — LSPLiskov Substitution: subtypes must be substitutable for base types
  • I — ISPInterface Segregation: prefer many specific interfaces over one fat one
  • D — DIPDepend on abstractions (interfaces), not concrete implementations
More Cheat Sheets

Explore Other Guides

Grow your full-stack and DevOps skills with our free developer reference library.

Get the Full C# .NET Core Cheat Sheet as PDF

Download the beautifully formatted PDF for offline reference — free forever. Perfect pinned on your second monitor or printed desk copy.

Join WhatsApp Channel