C#

  • By Language
  • 40 questions

What this round is for

C# interviews concentrate on three areas with great reliability: the value-versus-reference distinction and what it does to assignment, how LINQ actually executes, and the async rules whose violation produces deadlocks.

The language has changed substantially every few years, so knowing the modern answers - records, pattern matching, init accessors, nullable reference types - also signals that you have kept up.

The questions

Answer each one out loud before you open it. An answer you have read is not an answer you can give under pressure, which is the only kind that counts.

Q1 What is the difference between a value type and a reference type?

Show the answer Hide the answer

A value type holds its data directly and is copied on assignment; a reference type holds a reference to shared data.

Structs, int and DateTime are value types; classes, string and arrays are reference types. Nearly every surprising mutation bug traces to this.

What it is really testing. Whether you can predict what happens when each is assigned to a second variable.

Q2 When should you write a struct rather than a class?

Show the answer Hide the answer

When the value is small, immutable and created in large numbers, so avoiding heap allocation matters.

A large mutable struct is a reliable source of confusion, because every assignment and parameter pass silently copies it.

What it is really testing. Whether you know a large mutable struct is a problem.

Q3 Why does string behave like a value type?

Show the answer Hide the answer

Because it is immutable - every operation that appears to modify it returns a new object.

That is also why building a string in a loop with concatenation is quadratic, and why StringBuilder exists.

What it is really testing. Whether you connect immutability to the concatenation cost.

Q4 What are nullable reference types?

Show the answer Hide the answer

An opt-in compile-time analysis that warns where a reference might be null.

It is a warning system rather than a run-time guarantee - a library compiled without it can still hand you null in a non-nullable slot.

What it is really testing. Whether you know it is compile-time only. Many treat it as a guarantee.

Q5 What is the difference between a nullable value type and a nullable reference type?

Show the answer Hide the answer

A nullable value type is a real wrapper with a HasValue; a nullable reference type is annotation only.

The first changes the type at run time; the second disappears entirely at compile time, which is why their guarantees differ.

What it is really testing. Whether you know only one of them exists at run time.

Q6 What does LINQ deferred execution mean?

Show the answer Hide the answer

The query is a description; it runs when enumerated, and runs again on each enumeration.

Enumerating twice executes twice, which is merely wasteful in memory and serious when each item costs a database call.

What it is really testing. Whether you know enumerating twice runs the query twice.

Q7 How do you avoid double enumeration?

Show the answer Hide the answer

Materialise with ToList or ToArray when the sequence will be used more than once.

Returning IEnumerable from a public method is a decision to let the caller control when it runs, which needs to be deliberate.

What it is really testing. Whether you know when to materialise and when not to.

Q8 What is the difference between IEnumerable and IQueryable?

Show the answer Hide the answer

IEnumerable executes in memory; IQueryable builds an expression tree translated into the data source's own language.

Calling a method the provider cannot translate throws at run time, or silently fetches the whole table and filters locally.

What it is really testing. Whether you know an untranslatable call can silently fetch the whole table.

Q9 What does async/await do in C#?

Show the answer Hide the answer

It releases the thread while waiting, so a server handles more concurrent requests than it has threads.

It does not create a thread. The continuation resumes on a captured context unless you opt out with ConfigureAwait(false).

What it is really testing. Whether you know it does not create a thread.

Q10 Why should you never call .Result on a task?

Show the answer Hide the answer

It blocks the thread and can deadlock when a synchronisation context is involved.

The deadlock happens because the continuation needs the context the blocked thread is holding. It also wastes the thread the feature exists to free.

What it is really testing. Whether you can explain the deadlock rather than just saying do not do it.

Q11 When is async void acceptable?

Show the answer Hide the answer

Only for event handlers, because its exceptions cannot be caught by the caller.

An unhandled exception in an async void method usually takes the process down rather than propagating to a caller.

What it is really testing. Whether you know its exceptions escape the caller.

Q12 What is ConfigureAwait(false) for?

Show the answer Hide the answer

It tells the continuation not to resume on the captured context, which library code has no business doing.

It avoids unnecessary context switches and removes one cause of deadlock in applications that have a synchronisation context.

What it is really testing. Whether you know it belongs in library code specifically.

Q13 What is IDisposable for?

Show the answer Hide the answer

Releasing resources the garbage collector does not manage - files, connections, handles.

The collector reclaims memory and makes no promise about when, so anything holding an operating system resource needs explicit release.

What it is really testing. Whether you know the collector does not handle these resources.

Q14 What does using guarantee?

Show the answer Hide the answer

That Dispose runs at the end of the scope even if an exception is thrown.

Connection pool exhaustion caused by a path that returns early without disposing is the classic .NET production failure.

What it is really testing. Whether you can name the classic production failure it prevents.

Q15 Why should HttpClient not be disposed per request?

Show the answer Hide the answer

Disposing it frequently exhausts sockets, because they remain in a wait state after closing.

It is the inverse of the usual rule and catches people who correctly learned to dispose everything else.

What it is really testing. Whether you know this exception to the usual rule.

Q16 What is the difference between throw and throw ex?

Show the answer Hide the answer

throw rethrows preserving the original stack trace; throw ex resets it to the current line.

That one word is regularly the difference between a five-minute diagnosis and an afternoon of guessing.

What it is really testing. Whether you know the stack trace difference. It is a frequent real problem.

Q17 What is an exception filter?

Show the answer Hide the answer

A when clause that decides whether to catch without unwinding the stack first.

Because the stack is not unwound, the original state is still available for debugging, which a catch-and-rethrow destroys.

What it is really testing. Whether you know the stack is not unwound, which is the actual benefit.

Q18 What is the difference between a property and a field?

Show the answer Hide the answer

A field stores data; a property is a method pair that looks like a field.

Because adding logic to a property does not change calling code, C# never developed the reflexive getter-and-setter habit of languages without the feature.

What it is really testing. Whether you connect it to not breaking callers when logic is added later.

Q19 What does the init accessor do?

Show the answer Hide the answer

It allows a property to be set during object initialisation and never afterwards.

It gives immutability without a constructor full of assignments, and the compiler enforces it rather than a convention.

What it is really testing. Whether you know it gives immutability without constructor boilerplate.

Q20 What is a record and how does it differ from a class?

Show the answer Hide the answer

A record is a reference type with value-based equality and concise syntax.

Two records with the same values are equal, which is what you usually want for data. with expressions produce a modified copy rather than mutating.

What it is really testing. Whether you know equality is by value, which is the main reason to use one.

Q21 What is pattern matching used for in modern C#?

Show the answer Hide the answer

Testing shape and extracting values in one expression - types, properties, tuples, lists and ranges.

Combined with switch expressions it replaces chains of if-else and lets the compiler check that cases are covered.

What it is really testing. Whether you connect it to exhaustiveness checking.

Q22 What is the difference between a switch statement and a switch expression?

Show the answer Hide the answer

A statement executes branches; an expression returns a value and requires every path to produce one.

The expression form has no fall-through and throws if nothing matches, so a missing case fails loudly.

What it is really testing. Whether you know the expression form fails loudly on a missing case.

Q23 What are extension methods and why do they matter?

Show the answer Hide the answer

Methods added to an existing type without modifying it, compiled as ordinary static calls.

They are the mechanism that made LINQ possible - Where and Select are extensions on IEnumerable, not members of any collection.

What it is really testing. Whether you know LINQ itself is built on extension methods.

Q24 What is the difference between an abstract class and an interface in C#?

Show the answer Hide the answer

An abstract class may hold state; an interface declares a contract and now allows default implementations.

Default interface methods narrowed the difference, but a class may still inherit only one base and many interfaces.

What it is really testing. Whether you know default implementations exist now.

Q25 What is a delegate?

Show the answer Hide the answer

A type-safe reference to a method, which is what events and callbacks are built on.

Func and Action are the generic built-in forms, and a lambda is syntax for creating one inline.

What it is really testing. Whether you connect delegates to events and lambdas.

Q26 What is the difference between Func and Action?

Show the answer Hide the answer

Func returns a value; Action does not.

Predicate is a specialised Func returning bool. Knowing which to use is mostly a matter of whether there is a result.

What it is really testing. Whether you know Predicate is a specialised case.

Q27 What is a closure in C# and what does it capture?

Show the answer Hide the answer

A lambda capturing variables from its enclosing scope - and it captures the variable, not the value.

Capturing a loop variable used to share one binding across iterations; foreach was changed to give each iteration its own.

What it is really testing. Whether you know it captures the variable rather than its value.

Q28 What is the difference between IEnumerable and IEnumerator?

Show the answer Hide the answer

IEnumerable can produce an enumerator; IEnumerator walks the sequence and holds position.

foreach calls GetEnumerator for you, which is why a custom type supporting foreach only needs the one method.

What it is really testing. Whether you know foreach only needs GetEnumerator.

Q29 What does yield return do?

Show the answer Hide the answer

It builds a state machine that produces values lazily as they are requested.

Nothing in the method body runs until the sequence is enumerated, which surprises people expecting argument validation to happen at the call.

What it is really testing. Whether you know argument validation is deferred too, which causes confusing bugs.

Q30 What is boxing and why does it cost?

Show the answer Hide the answer

Wrapping a value type in an object so it can be treated as a reference type.

It allocates on the heap and copies, so boxing in a tight loop is a steady source of garbage collection pressure.

What it is really testing. Whether you connect it to garbage collection pressure in hot loops.

Q31 What are Span and Memory for?

Show the answer Hide the answer

Working with slices of existing memory without allocating a copy.

They are why modern .NET parsing is dramatically faster than it used to be, with no unsafe code required.

What it is really testing. Whether you know why modern parsing got faster without unsafe code.

Q32 What is the difference between a Task and a Thread?

Show the answer Hide the answer

A Thread is an operating system thread; a Task is a unit of work usually run on a pooled thread.

Creating threads directly is almost always wrong - the pool manages reuse, and Task composes with async.

What it is really testing. Whether you know creating threads directly is usually wrong.

Q33 What is a CancellationToken for?

Show the answer Hide the answer

Cooperatively signalling that work should stop - a timeout, a disconnected client, a user cancelling.

It must be passed through and checked; it cannot forcibly stop anything, which is why it is cooperative rather than pre-emptive.

What it is really testing. Whether you know it cannot force anything to stop.

Q34 What is dependency injection in .NET?

Show the answer Hide the answer

Supplying a class's dependencies from outside, with the built-in container resolving them by registered type.

The lifetimes - singleton, scoped, transient - are where mistakes happen, particularly injecting a scoped service into a singleton.

What it is really testing. Whether you know lifetimes are where the real mistakes happen.

Q35 What is the difference between singleton, scoped and transient lifetimes?

Show the answer Hide the answer

Singleton lasts for the application, scoped for a request, transient for each resolution.

Capturing a scoped service inside a singleton keeps the first request's instance alive forever, which is a subtle and serious bug.

What it is really testing. Whether you can name the captured-scoped-service bug.

Q36 What does the garbage collector's generational model assume?

Show the answer Hide the answer

That most objects die young, so young generations are collected more often and cheaply.

Objects surviving several collections are promoted. The large object heap is handled separately and is not compacted by default.

What it is really testing. Whether you know the large object heap behaves differently.

Q37 What is a finalizer and why avoid it?

Show the answer Hide the answer

A method run before collection - avoided because its timing is unpredictable and it delays reclamation.

An object with a finalizer survives an extra collection cycle. Dispose with a using block is the correct mechanism.

What it is really testing. Whether you know an object with a finalizer survives an extra cycle.

Q38 What is the difference between const and readonly?

Show the answer Hide the answer

const is compiled into the call site at build time; readonly is set at run time and may vary per instance.

Changing a const in a library means recompiling every consumer, because the old value was baked into their assemblies.

What it is really testing. Whether you know const values are baked into consuming assemblies.

Q39 What does ahead-of-time compilation change for C#?

Show the answer Hide the answer

It produces a native binary with fast start-up and no runtime dependency.

That makes C# viable for command-line tools and serverless functions where JIT warm-up previously ruled it out.

What it is really testing. Whether you know it removed the start-up objection.

Q40 Where is C# strong and where is it not?

Show the answer Hide the answer

Strong for backend services, desktop, games through Unity and cross-platform apps; weaker where the ecosystem matters more.

Data science and machine learning happen overwhelmingly in Python, and no amount of language quality changes which libraries exist.

What it is really testing. Whether you can name a weakness honestly rather than advocating.

Two things worth doing in the room

  • When asked about async, be precise that await releases a thread rather than creating one. That single clarification separates people who use the feature from people who understand it.
  • If a question is about a resource, mention disposal. Connection and socket exhaustion are the failures that actually take .NET applications down in production.