C# interviews tend to test two things at once: whether you understand what the runtime is doing underneath your code, and whether you can write ordinary, maintainable C# under mild pressure. The questions below are the ones that come up again and again, grouped by the level they usually appear at. Each answer gives the core explanation, a short code sample where it helps, and a note on what the interviewer is really checking.
Technical facts here are taken from Microsoft’s own C# and .NET documentation. Interview formats vary by employer; the “what they are checking” notes are general guidance, not a description of any particular company’s process.
Questions for freshers and junior developers
1. What is the difference between a value type and a reference type?
Microsoft’s C# reference puts it plainly: variables of reference types store references to their data (objects), while variables of value types directly contain their data. With reference types, two variables can point at the same object, so a change through one is visible through the other. With value types, each variable has its own copy, except where you pass it with ref, in or out.
var a = new List<int> { 1, 2 };
var b = a; // copies the reference
b.Add(3); // a.Count is now 3
int x = 1;
int y = x; // copies the value
y = 2; // x is still 1
Reference types are declared with class, interface, delegate and record; object, string and dynamic are the built-in reference types. struct and enum declare value types.
What they are checking: that you can predict what an assignment does. A good follow-up answer mentions that string is a reference type that behaves like a value in practice because it is immutable.
2. What are boxing and unboxing, and why should you care?
Boxing converts a value type to object or to an interface it implements; unboxing extracts it back. Boxing is implicit and unboxing is explicit. Microsoft’s guide explains that boxing allocates an object on the managed heap and copies the value into it, and describes both operations as computationally expensive compared with simple assignment.
int i = 123;
object o = i; // boxing
int j = (int)o; // unboxing: OK
short s = (short)o; // InvalidCastException: the box holds an int
Unboxing must target the exact type that was boxed. Unboxing null throws a NullReferenceException.
What they are checking: awareness of hidden allocations, for example why generic collections such as List<int> are preferred over the old non-generic ArrayList.
3. What is the difference between an abstract class and an interface?
An abstract class can hold state (fields), constructors and a mix of implemented and abstract members, and a class can inherit from only one. An interface defines a contract that a class or struct can implement alongside other interfaces. Modern C# allows interfaces to include default implementations, which narrows the gap, but Microsoft’s interface reference is clear that interfaces can’t contain instance state: static fields are allowed, instance fields are not.
A practical answer: use an interface when unrelated types need the same capability (IComparable, IDisposable). Use an abstract base class when related types share real implementation and state.
4. What do const and readonly mean?
A const is a compile-time constant, initialised only where it is declared; Microsoft lists numbers, Boolean values, strings and the null reference as what a constant can hold. A readonly field can be assigned only in its declaration or in a constructor of the same class, so it can hold values known only at run time and can differ depending on which constructor ran. A subtle point interviewers like: compilers propagate constants into the code that uses them, so if a library changes a public const, code compiled against it must be recompiled to see the new value. That is why Microsoft advises against const for anything that may change, such as a version number.
5. What does the using statement do?
It guarantees that Dispose is called on an object that implements IDisposable when the block ends, even if an exception is thrown. Microsoft’s IDisposable.Dispose documentation recommends creating disposable objects with using so that resources such as files, streams and handles are released promptly.
using (var writer = new StreamWriter("log.txt"))
{
writer.WriteLine("Hello");
} // Dispose runs here
// C# 8+ declaration form: disposed at end of the enclosing scope
using var reader = new StreamReader("data.txt");
6. What is LINQ, and what is deferred execution?
LINQ is the set of query operators (Where, Select, GroupBy and so on) that work over sequences. Most of them are deferred: building the query does nothing until you enumerate it with foreach, ToList(), Count() or similar.
var evens = numbers.Where(n => n % 2 == 0); // nothing runs yet
numbers.Add(10);
var list = evens.ToList(); // runs now, includes 10
What they are checking: whether you know that enumerating a deferred query twice runs it twice, which matters if it hits a database.
Questions for experienced developers
7. How do async and await work, and when should you use Task.Run?
await pauses the method until the awaited task completes, without blocking the thread; the rest of the method runs as a continuation. Microsoft’s guidance draws the key line between I/O-bound and CPU-bound work:
- I/O-bound (network calls, database access, file reads and writes): use
asyncandawaitdirectly, withoutTask.Run. - CPU-bound (heavy calculation): use
await Task.Run(...)to move the work off the calling thread, and measure first, because the overhead may outweigh the benefit for small workloads.
8. Why is async void discouraged?
Microsoft’s documentation gives three reasons: exceptions thrown in an async void method cannot be caught outside it, such methods are hard to test, and callers may not expect them to be asynchronous. The one legitimate use is event handlers, which must return void.
9. Why is calling .Result or .Wait() on a task risky?
Blocking synchronously on asynchronous work can cause deadlocks, particularly where a synchronisation context expects the continuation to run on the blocked thread. Microsoft’s guidance is to use async and await all the way up the call stack. Its replacement table maps Task.Wait and Task.Result to await, Task.WaitAll to await Task.WhenAll, and Thread.Sleep to await Task.Delay. It also notes that .Result and Wait() wrap exceptions in AggregateException.
10. How would you run several independent calls concurrently?
Start all the tasks, then await them together with Task.WhenAll. When using LINQ to create tasks, Microsoft recommends forcing the sequence with ToArray() or ToList() so the tasks actually start.
async Task<User[]> GetUsersAsync(IEnumerable<int> ids)
{
var tasks = ids.Select(id => GetUserAsync(id)).ToArray();
return await Task.WhenAll(tasks);
}
Follow-up to expect: “What if there are 10,000 IDs?” A good answer mentions throttling, for example with SemaphoreSlim or Parallel.ForEachAsync, so you do not flood the downstream service.
11. Explain the dispose pattern and finalisers.
IDisposable exists for deterministic clean-up of unmanaged resources. Microsoft’s documentation sets out the rules interviewers look for:
Disposemust be safe to call more than once; calls after the first must be ignored and must not throw.- Other members may throw
ObjectDisposedExceptionafter disposal. - If a type owns unmanaged resources directly, a finaliser can release them when a consumer forgets to dispose. Wrapping the handle in a
SafeHandleis the preferred alternative. - When
Disposehas run, callGC.SuppressFinalize(this)so the garbage collector skips the finaliser.
Most application classes never need a finaliser; they just dispose the disposable objects they own.
12. What are records, and when would you use one?
Microsoft describes record as a modifier on a class or struct that makes the compiler generate value equality, a formatted ToString, and non-destructive mutation through with expressions. The underlying type still decides reference or value semantics.
public record Person(string FirstName, string LastName);
var p1 = new Person("Grace", "Hopper");
var p2 = p1 with { FirstName = "Margaret" }; // p1 unchanged
Console.WriteLine(p1 == new Person("Grace", "Hopper")); // True
Points that separate strong answers: positional record class properties are init-only by default, while record struct properties are read-write unless you declare readonly record struct; equality includes the run-time type; array properties compare by reference; and Microsoft advises against records for Entity Framework Core entities, which rely on reference equality.
13. What are nullable reference types?
They are compile-time annotations, not new types: string and string? are the same .NET type. The compiler tracks whether each reference is “not-null” or “maybe-null” and warns when you might dereference null. Microsoft’s reference stresses that there is no run-time checking. The null-forgiving operator ! only silences the warning; it cannot prevent a NullReferenceException. Since .NET 6, new projects enable the feature by default.
What they are checking: whether you treat warnings as design feedback. Sprinkling ! everywhere is a red flag.
14. How does garbage collection affect the way you write code?
The .NET garbage collector reclaims managed memory automatically, so you do not free objects yourself. It does not manage unmanaged resources, which is why IDisposable exists, and it does not stop you holding references longer than necessary. Common real-world leaks in C# come from static collections that only grow, and from event subscriptions that keep subscribers alive. Mentioning one of those from your own experience is far more convincing than reciting generations.
Practical tasks you may be given
Many employers add a short coding exercise. These are typical shapes, not a list of any company’s questions:
- Refactor a method that mixes database access, business rules and formatting. Expect to discuss dependency injection and testing.
- Write a LINQ query to group, filter and sort a list of orders, then explain when it executes.
- Fix an async bug, often a
.Resultcall or anasync voidmethod swallowing an exception. - Design a small class such as a rate limiter or an LRU cache, and talk through thread safety.
- Read unfamiliar code and explain what it does. Narrate your reasoning out loud; silence is harder to assess than a wrong guess you then correct.
How to prepare in a week
- Days 1 and 2: type system: value and reference types, boxing, records, nullable reference types. Write the examples above yourself and change them until you can predict the output.
- Days 3 and 4: async and LINQ. Build a tiny console app that calls a public API several times with
Task.WhenAll. - Day 5:
IDisposable, exceptions and logging. - Day 6: two timed practice problems, spoken aloud.
- Day 7: prepare two project stories: a bug you tracked down and a design decision you would change now.
Your CV gets you into the room, so make it show the .NET versions, frameworks (ASP.NET Core, Entity Framework Core) and results you will talk about. The software engineer resume builder has sections suited to technical roles, and the resume examples show how to phrase project outcomes. Web-focused .NET developers may also find the web developer resume builder a better fit.
Frequently asked questions
Which C# topics come up most in interviews for freshers?
Value and reference types, object-oriented basics (classes, interfaces, inheritance), collections and LINQ, exceptions, and the using statement. Expect at least one small coding exercise.
What do interviews for experienced C# developers focus on?
Async and concurrency, memory and disposal, API design, testing, and real project trade-offs. Interviewers often ask you to explain a production issue you solved.
Do I need to know the latest C# version?
You should know the features you use and be aware of widely adopted ones such as records, pattern matching and nullable reference types. Be honest about which versions you have used in production.
Is C# knowledge enough, or will I be asked about .NET frameworks?
Most roles also test the framework the team uses, commonly ASP.NET Core for web APIs and Entity Framework Core for data access. Check the job advert and prepare for those specifically.
Sources
- Built-in reference types / reference types (C# reference), Microsoft Learn
- Boxing and Unboxing (C# Programming Guide), Microsoft Learn
- Introduction to record types in C#, Microsoft Learn
- Nullable reference types (C# reference), Microsoft Learn
- Asynchronous programming scenarios, Microsoft Learn
- IDisposable.Dispose Method, Microsoft Learn
- The const keyword (C# reference), Microsoft Learn
- readonly keyword (C# reference), Microsoft Learn
- interface keyword (C# reference), Microsoft Learn
