Type System
C# is strongly typed. Every variable has a type known at compile time.
Value Types
Stored directly on the stack. Copying creates an independent copy.
int count = 42;
double price = 9.99;
bool isActive = true;
char letter = 'A';
decimal money = 100.50m; // high precision for financial
Structs
Custom value types:
public struct Point
{
public double X { get; init; }
public double Y { get; init; }
}
var p = new Point { X = 1.0, Y = 2.0 };
Enums
public enum Status { Active, Inactive, Pending }
var s = Status.Active;
Reference Types
Stored on the heap. Variables hold references, not the data itself.
string name = "Alice"; // string is a reference type
int[] numbers = [1, 2, 3]; // collection expression (.NET 8+)
object anything = 42; // boxing: value type -> object
Nullable Reference Types
C# 8+ has nullable reference types (NRT). Enabled by default in .NET 6+.
string name = "Alice"; // non-null by default
string? maybe = null; // explicitly nullable
// Compiler warns on potential null dereference
int len = maybe.Length; // Warning: maybe may be null
int len = maybe?.Length ?? 0; // Safe: null-conditional + null-coalescing
Gotcha: NRT is a compile-time feature only. It doesn’t prevent null at runtime. Libraries without NRT annotations can still pass null to your code.
Pattern Matching
Modern C# has powerful pattern matching:
string Describe(object obj) => obj switch
{
int n when n > 0 => "positive integer",
int n when n < 0 => "negative integer",
int => "zero",
string s => $"string of length {s.Length}",
null => "null",
_ => "something else"
};
Records
Immutable data types with value equality (.NET 5+):
public record User(string Name, string Email);
var alice = new User("Alice", "alice@example.com");
var clone = alice with { Email = "new@example.com" };
// Value equality (not reference equality)
var same = new User("Alice", "alice@example.com");
Console.WriteLine(alice == same); // True
Tip: Use
recordfor DTOs, API responses, and any data that shouldn’t be mutated after creation. Userecord structfor small value types that need value equality.