These C# interview questions are for hiring managers and senior engineers screening .NET developers, and for candidates who want to know what a strong answer includes. They cover modern C# and .NET (the current long-term support release is .NET 10, which ships with C# 14), but they stay focused on habits that matter in any version: understanding types and memory, writing correct async code, and building services a team can maintain. Choose 6 to 8 questions that fit the role. After each answer, ask the candidate where they've used it, since real examples show depth better than definitions.
What a strong C# interview checks
- Type system: value vs reference types, records, nullability and when each one fits.
- Async correctness: async and await without deadlocks, blocked threads or lost exceptions.
- Collections and LINQ: readable queries that don't hide slow database calls or repeated enumeration.
- Memory and performance: how the garbage collector works and when allocation matters.
- Modern .NET practice: dependency injection, configuration, logging, testing and EF Core.
- Collaboration: clear code reviews, sensible refactoring and owning production issues.
C# interview questions: language fundamentals
1. What's the difference between a value type and a reference type?
What good looks like: value types (structs, enums, and primitives like int) hold their data directly, so assignment copies the value. Reference types (classes, arrays, strings, delegates) hold a reference, so two variables can point to the same object. A strong candidate corrects the myth that value types "always live on the stack": a struct field inside a class lives on the heap with the object.
Red flag: thinking that passing a class to a method copies the object.
2. When would you use a record instead of a class or struct?
What good looks like: records give value-based equality, a readable ToString(), and non-destructive changes with with expressions, which suits DTOs, messages and other immutable data. record class is a reference type and record struct is a value type. Plain classes fit objects with identity and behavior, such as a service or an entity that changes over time.
3. What do nullable reference types change?
What good looks like: with <Nullable>enable</Nullable>, the compiler treats string as non-nullable and string? as maybe-null, and warns about possible null dereferences. It's a compile-time analysis, so nothing changes at runtime and data from outside (JSON, databases) still needs validation. Strong candidates use the null-forgiving operator ! sparingly.
Red flag: sprinkling ! everywhere to silence warnings.
4. Why are strings immutable, and when do you use StringBuilder?
What good looks like: every change to a string creates a new string, which makes strings safe to share and use as dictionary keys. In a loop with many appends, that creates lots of garbage, so StringBuilder is better. For a few pieces, interpolation or string.Join is fine and easier to read.
5. What does pattern matching give you in modern C#?
What good looks like: switch expressions with type, property, relational and list patterns, such as order switch { { Total: > 1000 } => "review", _ => "auto" }. They replace long if-else chains with code the compiler can check. Strong candidates mention that the compiler warns when a switch expression doesn't cover every case.
6. What are primary constructors, and are there any gotchas?
What good looks like: since C# 12, classes and structs can declare parameters on the type itself, like class OrderService(IOrderRepo repo), which removes boilerplate for injected dependencies. The gotcha: in a class, the parameters aren't read-only fields, so they can be reassigned. Teams that want that safety assign them to readonly fields.
7. What does the using statement do, and when do you need it?
What good looks like: using calls Dispose() when the scope ends, even if an exception is thrown, which releases unmanaged resources like file handles, database connections and sockets. await using does the same for IAsyncDisposable. The short using var declaration disposes at the end of the enclosing block.
Async, LINQ and performance
8. What actually happens when you await a Task?
What good looks like: if the task isn't finished, the method returns to its caller and the rest of the method runs later as a continuation, so no thread sits blocked waiting for I/O. A strong candidate knows async is about not blocking threads during I/O, not about running things in parallel, and uses Task.WhenAll to run independent calls concurrently.
9. Why is calling .Result or .Wait() on a task risky?
What good looks like: it blocks a thread while waiting. In apps with a synchronization context (older ASP.NET, WPF, WinForms), that can deadlock, because the continuation needs the very thread that is blocked. In ASP.NET Core it doesn't deadlock the same way but still wastes thread-pool threads and hurts throughput under load. The answer is async all the way down.
Red flag: "async void is fine for any method." It should be limited to event handlers, since its exceptions can't be awaited or caught by the caller.
10. How do you support cancellation in an async API?
What good looks like: accept a CancellationToken parameter, pass it to every async call down the chain (HTTP, EF Core, streams), and check it in long loops. In ASP.NET Core, an action can take the token bound to the request, so work stops when the client disconnects.
11. What's the difference between IEnumerable and IQueryable?
What good looks like: IEnumerable<T> runs LINQ in memory with delegates. IQueryable<T> builds an expression tree that a provider like EF Core translates to SQL. Calling ToList() or AsEnumerable() too early pulls the whole table into memory and filters it there.
12. What is deferred execution in LINQ, and how can it bite you?
What good looks like: most LINQ operators don't run until you enumerate the result. Enumerating the same query twice runs it twice, which can mean two database calls or two slow computations. Strong candidates materialize once with ToList() when they need the results more than once, and know that the data may have changed between enumerations.
13. How does garbage collection work in .NET?
What good looks like: the GC is generational. New objects start in generation 0, which is collected often and cheaply, and survivors move to generations 1 and 2. Large objects (85,000 bytes and up) go on the large object heap. Strong candidates reduce allocation in hot paths with Span<T>, pooling (ArrayPool<T>) or structs, and only after measuring.
14. Why use IHttpClientFactory instead of creating HttpClient per request?
What good looks like: creating and disposing an HttpClient per call can exhaust sockets, because closed connections linger for a while. A single static client can miss DNS changes. IHttpClientFactory (or a long-lived client with PooledConnectionLifetime set) pools handlers correctly and works well with typed clients and resilience policies.
Modern .NET practice
15. Explain the Singleton, Scoped and Transient lifetimes in .NET dependency injection.
What good looks like: Singleton means one instance for the app's lifetime, Scoped means one per request (or per scope), and Transient means a new instance every time it's resolved. The classic bug is a captive dependency: a Singleton that takes a Scoped service, like an EF Core DbContext, keeps it alive far too long and shares it across threads. Scope validation in development catches this.
Red flag: registering DbContext as a Singleton.
16. An API endpoint using EF Core gets slower as data grows. What do you check?
What good looks like: log the generated SQL, then look for N+1 queries from lazy loading, missing indexes, loading whole entities when a projection with Select would do, and missing pagination. Use AsNoTracking() for read-only queries. They'd measure with logs or a profiler before and after each change.
17. How do you test a class that depends on the current time and an external API?
What good looks like: inject the dependencies instead of calling them directly. .NET 8 added TimeProvider, which can be replaced with a fake in tests, and the API client sits behind an interface or uses a fake HttpMessageHandler. Tests use xUnit, NUnit or MSTest, cover error paths like timeouts, and for ASP.NET Core, WebApplicationFactory supports in-memory integration tests.
18. How should configuration and secrets work in an ASP.NET Core app?
What good looks like: layered configuration from appsettings.json, environment-specific files, environment variables and a secret store such as Azure Key Vault or AWS Secrets Manager, bound to typed classes with the options pattern. User Secrets are for local development only. Nothing sensitive goes in source control.
Behavioral (STAR)
19. Tell me about a production bug in a .NET service you owned.
What good looks like: a clear Situation and Task, the Actions they took to reproduce and diagnose it (logs, traces, a failing test), and a Result that prevented a repeat, such as a test, an alert or a design change. They own their part of it.
Red flag: no clear role in the fix, or a story where the cause was always someone else.
20. Describe a refactor or upgrade you led, such as moving from .NET Framework to modern .NET.
What good looks like: how they scoped it, how they reduced risk with tests and small steps, how they handled libraries that didn't support the new version, and a measurable Result like faster builds, lower hosting cost or fewer incidents.
21. Tell me about feedback in a code review that changed how you write code.
What good looks like: a specific comment, why it stung or surprised them, what they learned, and how they now pass that lesson on in their own reviews. It shows they can take feedback and grow from it.
A simple scoring rubric
Running this interview with AI
For high-volume .NET hiring, an adaptive AI interviewer can take the first conversation off your senior engineers' calendars. NTRVSTA lets you customize the interview for each role, so you can load your own C# questions, including scenarios like the slow EF Core endpoint. The interviewer adjusts difficulty to each answer: a candidate who explains async and DI lifetimes well gets harder follow-ups, while one who struggles gets simpler ones. Behavioral questions use the STAR method, and the hint system lets you see how a candidate responds to guidance.
You get a score breakdown covering technical skills, English proficiency and communication, plus video snippets of the moments that matter. It's worth reading how AI interviews are scored and our comparison of AI interview software first. For related roles, see our backend developer and software engineer interview questions, and the software engineer job description template if you're writing the posting.
Questions
Which .NET version should C# interview questions assume?
Assume a current long-term support release, which is .NET 10 as of late 2026, but don't penalize candidates who work on .NET 8 or older .NET Framework code. Ask what version they use and score their reasoning, not whether they know the newest syntax.
Should a C# interview include live coding?
A short, realistic exercise helps in a later round, such as fixing a bug in a small service or writing a LINQ query against sample data. In the first round, conceptual and scenario questions tell you enough to decide who moves forward.
How do I tell a strong mid-level C# developer from a senior one?
Mid-level developers answer the language questions correctly and give working solutions. Seniors also explain the trade-offs, such as allocation cost, async pitfalls, DI lifetimes and EF Core query behavior, and talk about how they guide a team through those choices.
Want to see a C# first round run by an adaptive AI interviewer? Grab a 20-minute demo slot, or try a sample interview yourself.




