C# Cheatsheet

LINQ, async/await, generics, delegates, OOP & .NET essentials

Language
Contents

Basics & Types

// Data types
int i = 42;        long l = 100L;     byte b = 255;
float f = 3.14f;   double d = 3.14;   decimal m = 3.14m;
bool flag = true;  char c = 'A';       string s = "hello";
var x = 10;         // type inference

// String interpolation
string name = "Alice";
Console.WriteLine($"Hello {name}, age {30}");
string raw = @"C:\path\file";  // verbatim string

// Arrays
int[] arr = { 1, 2, 3 };
int[,] matrix = new int[3,4];   // 2D array
int[][] jagged = new int[3][];  // jagged array

// Casting
double d2 = (double)i;          // explicit cast
int i2 = Convert.ToInt32("42");
int.TryParse("42", out int result);
🏛️

OOP & Classes

public class Person {
    public string Name { get; set; }
    public int Age { get; init; }  // init-only (C# 9)
    public string Email { get; private set; }

    public Person(string name, int age) {
        Name = name; Age = age;
    }

    public override string ToString()
        => $"{Name} ({Age})";
}

// Inheritance
public class Student : Person {
    public string School { get; set; }
    public Student(string n, int a, string s)
        : base(n, a) { School = s; }
}

// Interface
public interface IRepository<T> {
    T GetById(int id);
    void Add(T item);
    IEnumerable<T> GetAll();
}

// Abstract class
public abstract class Shape {
    public abstract double Area();
}
📦

Collections

using System.Collections.Generic;

// List
var list = new List<int> { 1, 2, 3 };
list.Add(4);  list.Remove(2);  list.Contains(3);
list.Sort();  list.Reverse();  list.Count;

// Dictionary
var dict = new Dictionary<string, int> {
    ["a"] = 1, ["b"] = 2
};
dict.TryGetValue("a", out var val);
dict.ContainsKey("a");

// HashSet
var set = new HashSet<int> { 1, 2, 3 };
set.Add(4);  set.Contains(1);
set.UnionWith(otherSet);
set.IntersectWith(otherSet);

// Queue & Stack
var q = new Queue<int>();  q.Enqueue(1); q.Dequeue();
var s = new Stack<int>();  s.Push(1);     s.Pop();
🔗

LINQ

using System.Linq;

var nums = new List<int> { 1,2,3,4,5,6,7,8,9,10 };

// Method syntax (preferred)
var evens = nums.Where(n => n % 2 == 0);
var doubled = nums.Select(n => n * 2);
var first = nums.First(n => n > 5);       // 6
var any = nums.Any(n => n > 5);           // true
var all = nums.All(n => n > 0);           // true
var sum = nums.Sum();
var avg = nums.Average();
var max = nums.Max();
var ordered = nums.OrderByDescending(n => n);
var groups = nums.GroupBy(n => n % 2 == 0);
var distinct = nums.Distinct();
var taken = nums.Take(3).Skip(1);
var flat = nested.SelectMany(x => x);

// Query syntax
var query = from n in nums
            where n % 2 == 0
            orderby n descending
            select n * 2;

Async/Await

public async Task<string> FetchDataAsync(string url) {
    using var client = new HttpClient();
    var response = await client.GetAsync(url);
    return await response.Content.ReadAsStringAsync();
}

// Parallel tasks
var task1 = FetchDataAsync("url1");
var task2 = FetchDataAsync("url2");
await Task.WhenAll(task1, task2);

// Task.Run for CPU-bound work
var result = await Task.Run(() => HeavyComputation());

// Cancellation
var cts = new CancellationTokenSource();
cts.CancelAfter(TimeSpan.FromSeconds(5));
await DoWorkAsync(cts.Token);

// IAsyncEnumerable (C# 8)
async IAsyncEnumerable<int> GetNumbersAsync() {
    for (int i = 0; i < 10; i++) {
        await Task.Delay(100);
        yield return i;
    }
}
📡

Delegates & Events

// Delegate
delegate int MathOp(int a, int b);
MathOp add = (a, b) => a + b;
add(3, 4);  // 7

// Built-in delegates
Func<int, int, int> multiply = (a, b) => a * b;
Action<string> log = msg => Console.WriteLine(msg);
Predicate<int> isEven = n => n % 2 == 0;

// Events
public class Button {
    public event EventHandler Clicked;
    public void Click()
        => Clicked?.Invoke(this, EventArgs.Empty);
}

var btn = new Button();
btn.Clicked += (sender, e) => Console.WriteLine("Clicked!");
📐

Generics

// Generic class
public class Result<T> {
    public bool IsSuccess { get; }
    public T Value { get; }
    public string Error { get; }

    public static Result<T> Ok(T value)
        => new() { IsSuccess = true, Value = value };
    public static Result<T> Fail(string err)
        => new() { Error = err };
}

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

// where T : class        — reference type
// where T : struct       — value type
// where T : new()        — parameterless ctor
// where T : BaseClass
// where T : IInterface
🔀

Pattern Matching

// Switch expression (C# 8+)
string Classify(int n) => n switch {
    < 0 => "negative",
    0   => "zero",
    > 0 => "positive"
};

// Type pattern
if (obj is string s) { Console.WriteLine(s.Length); }

// Property pattern
if (person is { Age: >= 18, Name: "Alice" }) { }

// Tuple pattern
string RockPaperScissors(string p1, string p2)
    => (p1, p2) switch {
        ("rock", "scissors") => "P1 wins",
        ("scissors", "paper") => "P1 wins",
        ("paper", "rock") => "P1 wins",
        _ when p1 == p2 => "Tie",
        _ => "P2 wins"
    };
📦

Nullable & Records

// Nullable value types
int? nullable = null;
int val = nullable ?? 0;          // null coalescing
int val2 = nullable ??= 10;      // assign if null
nullable?.ToString();               // null-conditional

// Record (C# 9) — immutable reference type
public record Person(string Name, int Age);
var p = new Person("Alice", 30);
var p2 = p with { Age = 31 };    // non-destructive mutation

// Record struct (C# 10)
public record struct Point(int X, int Y);

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

// File-scoped namespace (C# 10)
namespace MyApp;   // instead of { ... }
🔧

Common Patterns

// using statement (dispose pattern)
using var stream = File.OpenRead("file.txt");
using var reader = new StreamReader(stream);

// Exception handling
try {
    var data = await FetchDataAsync(url);
} catch (HttpRequestException ex) when (ex.StatusCode == 404) {
    Console.WriteLine("Not found");
} catch (Exception ex) {
    Console.WriteLine(ex.Message);
} finally {
    // cleanup
}

// Dependency Injection (ASP.NET)
builder.Services.AddScoped<IUserService, UserService>();
builder.Services.AddSingleton<ICacheService, RedisCacheService>();

// dotnet CLI
// dotnet new console -n MyApp
// dotnet run
// dotnet build
// dotnet test
// dotnet add package Newtonsoft.Json