Understanding C# syntax is fundamental to writing clean, maintainable code. This guide covers variables, operators, expressions, and essential syntax patterns.
C# 8.0+ includes nullable reference types for better null safety:
// Value types - nullable with ?int? nullableInt = null;double? nullableDouble = 3.14;// Reference types with nullable context enabledstring? nullableName = null; // Can be nullstring nonNullName = "Alice"; // Cannot be null (compiler warning)// Null checkingif (nullableInt.HasValue){ int value = nullableInt.Value;}// Null-coalescingint result = nullableInt ?? 0; // Use 0 if null
bool a = true, b = false;bool and = a && b; // false - Logical AND (short-circuit)bool or = a || b; // true - Logical OR (short-circuit)bool not = !a; // false - Logical NOTbool xor = a ^ b; // true - Logical XOR// Short-circuit evaluationif (user != null && user.IsActive){ // user.IsActive only evaluated if user != null}
Use && and || for short-circuit evaluation - the right operand is only evaluated if necessary. This prevents null reference exceptions.
string? name = GetUserName();// Null-conditional member accessint? length = name?.Length; // null if name is null// Null-coalescingstring displayName = name ?? "Guest";// Null-coalescing assignment (C# 8.0+)name ??= "Default"; // Assign only if name is null// Chaining null-conditional operatorsint? count = user?.Profile?.Friends?.Count;
string name = "Alice";int age = 30;// String interpolation (preferred)string message = $"Hello, {name}! You are {age} years old.";// With expressionsstring info = $"Next year you'll be {age + 1}.";// Format specifiersdecimal price = 123.456m;string formatted = $"Price: {price:C2}"; // Price: $123.46// Verbatim interpolated stringsstring path = $@"C:\Users\{name}\Documents";
/// <summary>/// Calculates the total price including tax./// </summary>/// <param name="basePrice">The base price before tax</param>/// <param name="taxRate">The tax rate as a decimal (e.g., 0.08 for 8%)</param>/// <returns>The total price with tax included</returns>public decimal CalculateTotal(decimal basePrice, decimal taxRate){ return basePrice * (1 + taxRate);}
Used for local variables, parameters, and private fields:
public class Order{ private int orderId; // Private field private string _orderStatus; // Alternate: leading underscore public void ProcessPayment(decimal paymentAmount) { int transactionId = GetNextId(); var confirmationCode = GenerateCode(); }}
public void Example(){ int x = 10; // Scope: entire method if (x > 5) { int y = 20; // Scope: only inside if block Console.WriteLine(x + y); } // y is not accessible here - compile error // Console.WriteLine(y);}
// Traditional using statementusing (var reader = new StreamReader("file.txt")){ string content = reader.ReadToEnd();}// C# 8.0+ using declaration - no braces neededusing var reader = new StreamReader("file.txt");string content = reader.ReadToEnd();// Disposed at end of method scope
public class Person{ private string _name; // Expression-bodied method public string GetGreeting() => $"Hello, {_name}!"; // Expression-bodied property public string Name { get => _name; set => _name = value ?? throw new ArgumentNullException(nameof(value)); } // Read-only property public string DisplayName => $"Mr. {_name}"; // Expression-bodied constructor public Person(string name) => _name = name;}
// Badint d = 7;string s = "John";// Goodint daysUntilExpiration = 7;string customerName = "John";
Prefer var when type is obvious
// Good use of varvar customer = new Customer(); // Type is obviousvar orders = GetOrders(); // Return type clear from method name// Avoid var when type is unclearint count = GetCount(); // Better than var - return type not obvious
Use string interpolation over concatenation
// Avoidstring message = "Hello, " + name + "! Your balance is " + balance.ToString();// Preferstring message = $"Hello, {name}! Your balance is {balance:C}";