16 questions foundvar uses compile-time type inference; the compiler still gives it a single static type. It is not dynamic — the type is fixed once inferred.
var count = 5; // int
var name = "Sam"; // string
// count = "x"; // compile error
Real-world example Using var for obvious right-hand types (new lists, LINQ results) keeps code concise without losing type safety.
const is a compile-time constant embedded into callers and must be initialised inline; readonly is set once at runtime (declaration or constructor) and can vary per instance.
public const double Pi = 3.14159;
public readonly DateTime Created = DateTime.UtcNow;
Real-world example const for fixed math constants; readonly for values known only at construction, like an injected config value.
string overrides == and Equals to compare characters, so two strings with the same content are equal even if they are different objects.
var a = new string(new[]{'h','i'});
Console.WriteLine(a == "hi"); // True
Console.WriteLine(ReferenceEquals(a,"hi")); // False
Real-world example Comparing user input to an expected token by value, not reference.
By default integer overflow wraps silently (unchecked); a checked context throws OverflowException on overflow, which is safer for money/counters.
checked {
int max = int.MaxValue;
int y = max + 1; // throws OverflowException
}
Real-world example Wrapping financial calculations in checked so a silent overflow never corrupts a balance.
ref passes a variable by reference (must be initialised, can be read/written); out must be assigned inside the method (need not be initialised by caller); in passes by reference read-only for performance.
bool TryParse(string s, out int value);
void Swap(ref int a, ref int b);
double Length(in Vector v); // read-only
Real-world example TryParse patterns use out to return both success and the parsed value.
Interpolated strings usually compile to string.Format (or a DefaultInterpolatedStringHandler on modern .NET). Avoid it in hot logging paths where the message may not be emitted — use structured logging instead.
string s = $"User {id} at {DateTime.UtcNow}";
// logging: prefer logger.LogInformation("User {Id}", id);
Real-world example Structured logs let you query by the Id field later instead of parsing a formatted string.
'var' tells the compiler to INFER the variable's type from the right-hand side expression at COMPILE TIME — the variable is still strongly, statically typed exactly as if you'd written the type explicitly; 'var' is purely a syntax convenience, not a dynamic or loosely-typed declaration.
var count = 5; // inferred as int, fixed for the variable's lifetime
var name = "Sam"; // inferred as string
// count = "text"; // Error: count is still strictly typed as int
Real-world example Reducing verbosity for obviously-typed right-hand expressions, like 'var list = new List<string>();'.
Common follow-ups: Can you use 'var' for a field or property declaration, or only for local variables?
Value vs Reference Types
An auto-property (`public string Name { get; set; }`) lets you declare a property without writing an explicit backing field or accessor bodies — the compiler automatically generates a hidden private backing field and simple get/set accessor implementations for you.
public class Person {
public string Name { get; set; } = string.Empty; // compiler generates the backing field automatically
public int Age { get; init; } // init-only: settable only during object initialization
}
Real-world example Quickly defining simple data-holder properties on a class without writing repetitive backing-field boilerplate.
Common follow-ups: What does the 'init' accessor (instead of 'set') restrict about when a property can be assigned?
OOP
'ref' passes a variable BY REFERENCE, requiring it to be initialized before the call, and lets the method both read AND modify it; 'out' also passes by reference but doesn't require prior initialization, and the method MUST assign it before returning; 'in' passes by reference but READ-ONLY, preventing the method from modifying it (used mainly for performance with large structs, avoiding a copy).
void Increment(ref int x) { x++; } // must be initialized before calling
void TryParse(out int result) { result = 42; } // no need to initialize first, must be set inside
void ReadOnly(in int x) { /* x++; // Error: can't modify an 'in' parameter */ }
Real-world example Using 'out' for a TryParse-style method returning both a success bool and a result value; 'ref' for an in-place increment/swap operation.
Common follow-ups: Why would you use 'in' specifically for a large struct parameter rather than passing it normally by value?
Value vs Reference Types
String interpolation (`$"..."`) embeds expressions directly inside `{}` within a string literal, compiled internally into either a string.Format() call or (in modern .NET) a more efficient interpolated string handler — it's generally more readable than string.Format()'s positional placeholders and avoids the performance pitfalls of repeated '+' concatenation in a loop.
string name = "Sam";
int age = 30;
string message = $"{name} is {age} years old."; // readable, compiler-optimized
// Equivalent, more verbose alternatives:
string message2 = string.Format("{0} is {1} years old.", name, age);
string message3 = name + " is " + age + " years old.";
Real-world example Building a readable, formatted log message or user-facing display string combining multiple variable values.
Common follow-ups: Why is repeated string concatenation with '+' inside a LOOP specifically discouraged, in favor of StringBuilder?
String Handling & StringBuilder