C# Cheatsheet
Generics, Delegates, and Events
Use this C# reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Generic Methods
static T FirstOr<T>(IEnumerable<T> items, T fallback) { foreach (T item in items) return item; return fallback; }
Generics let one implementation work with many types while keeping compile-time type safety.
Generic Constraints
static T Create<T>() where T : new() { return new T(); } static int CountNamed<T>(IEnumerable<T> items) where T : INamed { return items.Count(x => x.Name.Length > 0); }
Constraints tell the compiler what operations are legal for T: class, struct, notnull, new(), base classes, and interfaces.
Delegates and Func/Action
Func<int, int> square = x => x * x; Action<string> log = message => Console.WriteLine(message); Predicate<int> positive = x => x > 0;
A delegate is a type-safe function reference. Func returns a value, Action returns void, and Predicate<T> returns bool.
Events
public class Button { public event EventHandler? Clicked; public void Click() => Clicked?.Invoke(this, EventArgs.Empty); }
Events expose subscription without letting outside code invoke the delegate directly. Use events for notifications, not request/response logic.
Extension Methods
public static class StringExtensions { public static bool IsBlank(this string? value) => string.IsNullOrWhiteSpace(value); } if (name.IsBlank()) { }
Extension methods are static methods called like instance methods. They are useful for small, discoverable helpers on types you do not own.
Attributes
[Obsolete("Use NewParser instead")] public class OldParser { } // System.Text.Json: rename a property on the wire public record Snapshot( [property: JsonPropertyName("id")] string Id, DateTime CreatedAt); // ASP.NET Core: routing + model validation public record CreateUser([Required, EmailAddress] string Email); // xUnit: data-driven test [Theory] [InlineData(2, 3, 5)] [InlineData(-1, 1, 0)] public void Add_Works(int a, int b, int expected) => Assert.Equal(expected, a + b);
Attributes attach metadata that the compiler, runtime, and frameworks read via reflection or source generators. [Obsolete] is compiler-level; most others come from the framework in use (routing, validation, serialization, tests).
Equality Quick Reference
| Type shape | Default equality |
|---|---|
class | reference equality unless overridden |
record class | value equality by properties |
struct | value equality, but consider implementing for performance |
string | value equality |
Override Equals and GetHashCode together when custom equality is needed.