Syntax
C# syntax tour: types, var, control flow, classes, records, generics, async/await, pattern matching.
C# — syntax tour
EXAMPLE
// ===== Primitives =====
int age = 30;
long id = 4_000_000_000L;
double pi = 3.14159;
decimal money = 49.95m; // use for money
bool ok = true;
char ch = 'A';
// Reference / nullable:
string name = "Alex";
string? maybe = null; // requires <Nullable>enable</Nullable>
// var inference:
var users = new List<string>();
var pairs = new Dictionary<string, int>();
// ===== Control flow =====
if (age >= 18) { /* ... */ } else { /* ... */ }
for (int i = 0; i < 5; i++) { /* ... */ }
foreach (var x in users) { /* ... */ }
while (cond) { /* ... */ }
do { /* ... */ } while (cond);
// Switch expression (modern):
string size = age switch {
0 or 1 => "baby",
< 10 => "small",
< 100 => "medium",
_ => "large",
};
// Pattern matching with property patterns:
string describe(object o) => o switch {
null => "nothing",
int n when n < 0 => "negative int",
int n => "int " + n,
string s => "string " + s,
{ } x => x.ToString() ?? "obj",
};
// ===== Classes + records =====
public class User
{
public int Id { get; }
public string Name { get; set; }
public User(int id, string name) { Id = id; Name = name; }
}
public record Order(int Id, string Customer, long TotalCents);
public record class OrderEntity(int Id) { public string? Note { get; init; } }
public record struct Point(int X, int Y);
// 'with' expressions (non-destructive update):
var p1 = new Point(1, 2);
var p2 = p1 with { X = 99 };
// ===== Generics =====
List<int> nums = new() { 1, 2, 3 };
Dictionary<string, int> ages = new() { ["Alex"] = 30 };
public static T First<T>(IReadOnlyList<T> xs) => xs[0];
// ===== async / await =====
public async Task<string> FetchAsync(string url)
{
using var http = new HttpClient();
return await http.GetStringAsync(url);
}
// ===== using + IDisposable =====
using var stream = File.OpenRead("a.txt");
// Disposed at end of scope.
// Long form:
using (var stream2 = File.OpenRead("b.txt")) { /* ... */ }
// ===== LINQ =====
using System.Linq;
var evens = new[] { 1, 2, 3, 4, 5 }.Where(n => n % 2 == 0).Select(n => n * n).ToList();
// ===== Tuples =====
(string Name, int Age) person = ("Alex", 30);
var (n, a) = person;
// ===== Patterns to internalise =====
// - Nullable reference types enabled in every project
// - record for value-shape DTOs
// - var for local readability
// - async / await at I/O boundaries
// - Pattern matching > nested ifs
// ===== Pitfalls =====
// - decimal vs double for money
// - .Result on Tasks -> deadlocks
// - Catching Exception broadly
// - Disabling nullable warnings -> hides real bugs
Why it matters
Modern C# is concise: var, record, pattern matching, switch expressions, nullable refs, async/await. Master those and the language stops being a wall of ceremony. Records + pattern matching alone reduce a startling amount of boilerplate.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Discussion
Loading…