C# interview questions test async/await, LINQ, the CLR, dependency injection, and the .NET ecosystem. C# (C Sharp) interviews for backend and enterprise roles often mix language questions with how you'd structure a real .NET application. This page covers 40 real C# interview questions with answers across four formats: multiple choice, written answers, spoken responses, and live coding challenges, the same mix used in modern technical interviews.
Practice each question in your browser with no signup required. Answers stay hidden until you attempt the question: type, speak, or code your response first, then compare it against the model answer. Questions range from fundamentals for your first developer job to scenario-based questions for senior roles, so you can find the gaps in your knowledge before the real interview.
40 questions with answersLast updated: Oct 19, 2026
Choose a question. Pick any of the 40 questions. They mix multiple choice, written, spoken, and coding, the same mix a real interviewer uses.
Attempt your answer. Select a multiple-choice option, type your written response, record a spoken answer, or write code in the editor.
Reveal the model answer. Once you have attempted the question, the model answer unlocks so you can compare it with yours.
Move to the next question. Track how many questions you have attempted with the progress bar at the top of the page.
Take a mock interview. When you are ready, try a full mock technical interview on Plaicer with AI-driven follow-up questions.
C# Interview Questions and Answers
0 of 40 attempted
1Multiple choice
How would you describe C# and what environments does it target?
Attempt the question first to reveal the answer.
Answer
C# is a multi-paradigm language running on the .NET runtime, targeting Windows desktop (WinForms, WPF), web (ASP.NET Core), mobile (Xamarin), and cloud applications.
2Written answer
Describe C#'s design goals and its relationship to the .NET ecosystem
Attempt the question first to reveal the answer.
Answer
C# was designed as a modern, simple, type-safe language for the .NET platform. It combines the power of C++ with the simplicity of Java, borrowing best practices from both. C# runs on the CLR, which provides memory management, garbage collection, and runtime type safety. The language supports multiple paradigms: object-oriented (classes, inheritance, polymorphism), functional (lambdas, LINQ), and procedural. C# evolves with each .NET release, adding features like nullable reference types, records, and pattern matching. The .NET ecosystem provides comprehensive libraries for web, desktop, mobile, and cloud development.
3Spoken answer
Walk through how you would design a REST API using ASP.NET Core with proper dependency injection
This browser cannot record audio. Answer the question out loud anyway, then compare yourself against the model answer below.
Attempt the question first to reveal the answer.
Answer
I created controllers inheriting from ControllerBase, each with actions returning IActionResult. I used dependency injection to inject services: private readonly IUserService _service; in the constructor. Services used interfaces for decoupling. I configured middleware: app.UseRouting() and app.UseEndpoints(). I implemented proper error handling, returning appropriate HTTP status codes. I used async actions: public async Task<IActionResult> GetUser(int id). Validation occurred in services, not controllers. I structured as Presentation → Service → Repository → Database, with interfaces between layers.
4Coding
Write an async method that fetches data from multiple APIs concurrently and combines results
public async Task<CombinedData> FetchDataAsync(string id) {
// Fetch from multiple APIs concurrently
}
Attempt the question first to reveal the answer.
Answer
public async Task<CombinedData> FetchDataAsync(string id) {
var task1 = FetchFromApiOneAsync(id);
var task2 = FetchFromApiTwoAsync(id);
var task3 = FetchFromApiThreeAsync(id);
await Task.WhenAll(task1, task2, task3);
return new CombinedData { Data1 = await task1, Data2 = await task2, Data3 = await task3 };
}
5Multiple choice
Explain the Common Language Runtime and its role in executing C# programs
Attempt the question first to reveal the answer.
Answer
The CLR compiles C# to Intermediate Language (IL), then JIT compiles to native code at runtime, enabling cross-platform execution and language interoperability.
6Written answer
Explain how the CLR enables language interoperability and manages program execution
Attempt the question first to reveal the answer.
Answer
The CLR is a virtual machine that compiles C# to Intermediate Language (IL), a platform-independent bytecode. At runtime, JIT (Just-In-Time) compilation converts IL to native machine code. Multiple languages (C#, VB.NET, F#) compile to IL, enabling interoperability: a C# class can inherit from a VB.NET class. CLR manages execution: memory allocation on the heap, garbage collection to reclaim unused objects, exception handling, and type safety through verification. This abstraction enables the same IL to run on Windows, Linux, and macOS without recompilation.
7Spoken answer
Describe a situation where you used async/await to improve application responsiveness
This browser cannot record audio. Answer the question out loud anyway, then compare yourself against the model answer below.
Attempt the question first to reveal the answer.
Answer
I had an API that made sequential calls to multiple external services, blocking the UI thread. Converting to async with Task.WhenAll() ran them in parallel. Each service method was async Task<T>. The controller action was async. This freed the UI thread, allowing other requests to be processed. Response time improved significantly without adding threads. I handled timeouts with CancellationToken and proper exception handling.
8Coding
Use LINQ to filter and transform a collection of products based on multiple criteria
public List<ProductSummary> GetDiscountedProducts(List<Product> products, decimal minDiscount) {
// Use LINQ to filter and transform
}
What is the .NET Framework and how does it support C# development?
Attempt the question first to reveal the answer.
Answer
.NET (and .NET Core/.NET 5+) provides the runtime, comprehensive standard library, and development tools for diverse application types.
10Written answer
Describe the components of .NET and how .NET Core differs from the full Framework
Attempt the question first to reveal the answer.
Answer
.NET provides CLR, Base Class Library (BCL) with collections, I/O, and reflection, and language compilers. The .NET Framework (Windows-only) includes additional libraries for WinForms, WPF, and ASP.NET. .NET Core (now .NET 5+) is cross-platform (Windows, Linux, macOS), open-source, and modular, allowing inclusion only of needed libraries. .NET Core enables containerization and cloud deployment. Modern development uses .NET 5+ for new projects; .NET Framework is in maintenance mode. ASP.NET Core (web framework) and Entity Framework Core (ORM) run on both platforms.
11Spoken answer
Explain how you would implement the observer pattern using delegates and events
This browser cannot record audio. Answer the question out loud anyway, then compare yourself against the model answer below.
Attempt the question first to reveal the answer.
Answer
I created a delegate: public delegate void OnOrderStatusChanged(Order order); and an event in the Order class. UI and notification services subscribed: order.StatusChanged += (o) => UpdateUI(o); When order status changed, I invoked the event: StatusChanged?.Invoke(this); Multiple handlers executed independently. Unsubscribing prevented memory leaks. This pattern decoupled order processing from its side effects.
12Coding
Implement a generic repository class that works with any entity type
public class Repository<T> : IRepository<T> where T : class {
private readonly DbContext _context;
// Implement CRUD operations
}
Attempt the question first to reveal the answer.
Answer
public class Repository<T> : IRepository<T> where T : class {
private readonly DbContext _context;
public Repository(DbContext context) { _context = context; }
public async Task<T> GetByIdAsync(int id) { return await _context.Set<T>().FindAsync(id); }
public async Task AddAsync(T entity) { await _context.Set<T>().AddAsync(entity); }
public void Remove(T entity) { _context.Set<T>().Remove(entity); }
public async Task SaveAsync() { await _context.SaveChangesAsync(); }
}
13Multiple choice
How does LINQ enable querying data sources in C#?
Attempt the question first to reveal the answer.
Answer
LINQ (Language Integrated Query) offers query methods (Where, Select, GroupBy) and SQL-like syntax that work with any data source via deferred execution.
14Written answer
Explain LINQ's deferred execution model and how it works with different data sources
Attempt the question first to reveal the answer.
Answer
LINQ uses deferred execution: queries don't run immediately when constructed, only when enumerated (in a foreach or ToList()). This enables composing queries: Where() filters, Select() transforms, both returning IEnumerable. The query is executed once during enumeration. Different providers handle different sources: LINQ-to-Objects for collections, LINQ-to-SQL for databases, LINQ-to-XML for XML. Each provider translates LINQ methods to the appropriate query format (SQL for databases). Deferred execution allows combining filters efficiently; executing too early causes unnecessary iteration.
15Spoken answer
Talk about a time you optimized LINQ queries by understanding deferred execution
This browser cannot record audio. Answer the question out loud anyway, then compare yourself against the model answer below.
Attempt the question first to reveal the answer.
Answer
I was executing a LINQ query in a loop, running the query thousands of times. Calling ToList() once before the loop cached results, reducing database hits from thousands to one. I also avoided Select(x => x.Property) in the query, letting the database handle filtering before retrieving data. Understanding that LINQ-to-SQL translates to SQL taught me to defer execution and push filters to the database.
16Coding
Create a class that publishes events when state changes occur
public delegate void OnStateChanged(StateChangedEventArgs args);
public class StateManager {
public event OnStateChanged StateChanged;
// Implement state change notification
}
Attempt the question first to reveal the answer.
Answer
public delegate void OnStateChanged(StateChangedEventArgs args);
public class StateManager {
public event OnStateChanged StateChanged;
private string _state;
public string State {
get { return _state; }
set {
if (_state != value) {
_state = value;
StateChanged?.Invoke(new StateChangedEventArgs { NewState = value });
}
}
}
}
17Multiple choice
Explain how properties provide controlled access to class members in C#
Attempt the question first to reveal the answer.
Answer
Properties use get and set accessors (can be private) to control field access, enabling validation, computed values, and notifications on changes.
18Written answer
Explain how properties enable encapsulation while providing convenient access syntax
Attempt the question first to reveal the answer.
Answer
Properties use get/set accessors (can be separate access levels: public get, private set). Behind the scenes, they typically wrap a private field. This enables validation in the setter, notifications via PropertyChanged event, and computed values in the getter. Example: public string Email { get; set; } is automatic, storing in a compiler-generated field. The syntax feels like field access but provides method-like control. Properties can be virtual for overriding or abstract in interfaces. This design provides data hiding while maintaining clean syntax.
19Spoken answer
Describe how you would structure a large application using dependency injection and interfaces
This browser cannot record audio. Answer the question out loud anyway, then compare yourself against the model answer below.
Attempt the question first to reveal the answer.
Answer
I structured the application: Domain (business logic), Application (use cases), Infrastructure (database, external services), Presentation (UI). Interfaces defined contracts between layers. Dependency injection injected implementations. The IoC container managed lifetimes. Adding new implementations didn't require changing existing code. Testing was easy: inject mocks of dependencies. This architecture scaled as the application grew.
20Coding
Implement a property with validation logic that throws exceptions for invalid values
public class User {
private string _email;
public string Email {
get { return _email; }
set {
// Add validation
}
}
}
Attempt the question first to reveal the answer.
Answer
public class User {
private string _email;
public string Email {
get { return _email; }
set {
if (string.IsNullOrWhiteSpace(value)) throw new ArgumentException("Email cannot be empty");
if (!value.Contains("@")) throw new ArgumentException("Invalid email format");
_email = value;
}
}
}
21Multiple choice
How do async and await keywords simplify asynchronous programming?
Attempt the question first to reveal the answer.
Answer
Async/await is syntactic sugar over Tasks that makes asynchronous code read like synchronous code while maintaining non-blocking execution.
22Written answer
Describe how async/await works with Tasks to enable responsive asynchronous code
Attempt the question first to reveal the answer.
Answer
Async methods return Task or Task<T>. Await pauses the method, returning control to the caller. When the awaited operation completes, execution resumes. This avoids blocking threads: a web server can handle many requests without creating threads for each. Async methods are compiled to state machines by the compiler. Tasks can wrap I/O operations (file, network) that don't require CPU. Combining async I/O with thread pools enables high concurrency without thread explosion. Exception handling works as expected: try-catch around awaits catches asynchronous exceptions.
23Spoken answer
Explain your approach to handling exceptions in asynchronous operations
This browser cannot record audio. Answer the question out loud anyway, then compare yourself against the model answer below.
Attempt the question first to reveal the answer.
Answer
I wrapped await calls in try-catch blocks. For multiple concurrent operations, I used Task.WhenAll() inside try-catch to catch any task's exception. I used TaskCompletionSource to convert callbacks to Tasks for consistent error handling. I ensured operations could be cancelled with CancellationToken. I logged exceptions before rethrowing or returning error responses.
24Coding
Sort a list of employees by multiple criteria using lambda expressions
public List<Employee> SortEmployees(List<Employee> employees) {
// Use OrderBy with lambda expressions
}
What are delegates and how do they enable callback mechanisms in C#?
Attempt the question first to reveal the answer.
Answer
Delegates define the signature of a method. Events build on delegates to enable the observer pattern, allowing multiple subscribers to handle notifications.
26Written answer
Explain delegates and events, and how they enable observer patterns
Attempt the question first to reveal the answer.
Answer
A delegate is a type-safe function pointer: public delegate void OnDataReceived(string data); declares a delegate type. A class can define an event: public event OnDataReceived DataReceived; Subscribers register: obj.DataReceived += handler; and unregister: obj.DataReceived -= handler; The owner publishes: DataReceived?.Invoke(data); This decouples publishers from subscribers. Multiple handlers can subscribe without knowing about each other. Events prevent subscribers from clearing others' handlers or invoking the event (public field would allow this). This pattern is fundamental to UI frameworks and observer implementations.
27Spoken answer
Walk through how you would implement a custom LINQ provider for a specific data source
This browser cannot record audio. Answer the question out loud anyway, then compare yourself against the model answer below.
Attempt the question first to reveal the answer.
Answer
I created an IQueryable provider implementing IQueryable<T> and IQueryProvider. The visitor pattern walked the expression tree, translating it to my data source's query format. I implemented methods like Where, Select, and GroupBy as extension methods. This allowed LINQ syntax to work with custom data sources without requiring the LINQ provider library.
28Coding
Create a simple LINQ query that demonstrates method chaining
public List<string> ProcessOrders(List<Order> orders) {
// Use LINQ methods: Where, Select, GroupBy, OrderBy
}
Explain lambda expressions and their role in functional programming in C#
Attempt the question first to reveal the answer.
Answer
Lambda expressions (x => x * 2) create inline functions, essential for LINQ queries and functional patterns. They capture local variables in closures.
30Written answer
Describe lambda syntax and how they integrate with LINQ and functional patterns
Attempt the question first to reveal the answer.
Answer
Lambda syntax is (parameters) => expression or (parameters) => { statements }. Examples: x => x * 2 or (x, y) => x + y. Lambdas capture local variables, creating closures. They integrate seamlessly with LINQ: list.Where(x => x > 10).Select(x => x.ToString()). Lambdas reduce boilerplate compared to anonymous methods or named functions. They enable functional patterns: Function<int, int> square = x => x * x. The compiler infers types from context. Lambdas can have side effects, though pure functions (no side effects) are preferred in LINQ for predictable execution.
31Spoken answer
Describe how you would use generics to create a reusable repository pattern
This browser cannot record audio. Answer the question out loud anyway, then compare yourself against the model answer below.
Attempt the question first to reveal the answer.
Answer
I defined IRepository<T> with methods like GetAsync, AddAsync, UpdateAsync, SaveAsync. Repository<T> implemented this, using Entity Framework Core internally. Controllers depended on IRepository, not the concrete class. Adding new entity types required minimal code: inherit Repository<Entity> or configure mapping. This pattern made testing easy: I created a mock repository returning test data.
32Coding
Implement a method that executes multiple async operations in parallel and waits for all
public async Task<T[]> ExecuteTasksInParallel<T>(params Task<T>[] tasks) {
// Execute tasks in parallel
}
How does dependency injection improve code testability and flexibility?
Attempt the question first to reveal the answer.
Answer
DI inverts control: classes depend on abstractions, not concrete implementations. DI containers manage object creation, enabling easy testing and configuration.
34Written answer
Explain how DI containers manage object lifecycles and dependencies
Attempt the question first to reveal the answer.
Answer
DI containers (e.g., Microsoft.Extensions.DependencyInjection) maintain a registry: IServiceCollection.AddScoped<IRepository, Repository>(); Scoped means one instance per request; Singleton means one globally; Transient means new each time. At runtime, requesting IRepository returns a Repository instance. The container recursively resolves dependencies: if Repository needs IDbContext, the container creates that first. Configuration in Startup or Program: services.AddScoped<IUserService>(sp => new UserService(sp.GetRequiredService<IRepository>())). Constructor injection receives dependencies. This decouples classes from instantiation, enabling testing (inject mocks) and runtime substitution without code changes.
35Spoken answer
Talk about migrating legacy code to use properties instead of public fields
This browser cannot record audio. Answer the question out loud anyway, then compare yourself against the model answer below.
Attempt the question first to reveal the answer.
Answer
Legacy code had public int Age; { get; set; }. I refactored to private int _age; public int Age { get { return _age; } set { _age = value; } }. This allowed adding validation later without changing callers. I gradually moved more logic into properties as needed. Properties are syntactic sugar for methods, maintaining backward compatibility while enabling encapsulation.
36Coding
Implement IDisposable correctly to manage unmanaged resources
public class DatabaseConnection : IDisposable {
private IntPtr _handle;
// Implement Dispose pattern
}
Attempt the question first to reveal the answer.
Answer
public class DatabaseConnection : IDisposable {
private IntPtr _handle;
private bool _disposed = false;
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing) {
if (!_disposed) {
if (disposing) { /* managed cleanup */ }
if (_handle != IntPtr.Zero) { CloseHandle(_handle); }
_disposed = true;
}
}
~DatabaseConnection() { Dispose(false); }
}
37Multiple choice
How does automatic garbage collection in C# manage memory differently from manual approaches?
Attempt the question first to reveal the answer.
Answer
GC automatically frees unreachable objects but doesn't manage unmanaged resources (file handles, database connections). IDisposable and using statements handle those.
38Written answer
Describe generational garbage collection and the finalization/disposal pattern
Attempt the question first to reveal the answer.
Answer
GC organizes heap into generations: Gen0 (new objects), Gen1 (survived one GC), Gen2 (old). GC collects Gen0 frequently, older generations rarely. This optimizes for objects dying young. Finalizers (~ClassName()) run before GC reclaims objects but add overhead. The IDisposable pattern is preferred: public void Dispose() { /* clean up */ } Using statements: using (var file = new StreamReader(path)) { } call Dispose automatically. For unmanaged resources (file handles, network sockets), implement IDisposable and use using statements. Modern using statements (C# 8+) simplify this. Finalizers are the safety net if Dispose wasn't called.
39Spoken answer
Explain how you would implement a plugin system using reflection and dependency injection
This browser cannot record audio. Answer the question out loud anyway, then compare yourself against the model answer below.
Attempt the question first to reveal the answer.
Answer
I used reflection: Assembly.GetExecutingAssembly().GetTypes() found all types. I filtered for implementations of IPlugin. For each, I registered with DI: services.AddScoped(pluginType). At runtime, requesting IEnumerable<IPlugin> gave all plugins. Each plugin was discovered and loaded without hardcoding. This enabled adding plugins by dropping assemblies in a folder.
40Coding
Use a dictionary to cache results and avoid redundant processing
public class DataCache {
private Dictionary<string, CachedData> _cache;
// Implement caching with dictionary
}
Attempt the question first to reveal the answer.
Answer
public class DataCache {
private Dictionary<string, CachedData> _cache = new();
public CachedData GetOrCompute(string key, Func<CachedData> compute) {
if (!_cache.TryGetValue(key, out var cached)) {
cached = compute();
_cache[key] = cached;
}
return cached;
}
}
Topics covered
C# and .NET fundamentals: the CLR, .NET Framework vs modern .NET
40 real C# interview questions across four formats: multiple choice (10), written answer (10), spoken answer (10), and coding (10).
Do I need to sign up to practice?
No. All 40 questions and model answers are free with no signup. You attempt each question first, and the model answer unlocks once you have engaged.
Who are these C# interview questions for?
Developers preparing for C# technical interviews at any level, from first job to senior engineer roles. Questions cover fundamentals through real-world scenarios.
What topics do the C# questions cover?
The questions cover the CLR, modern .NET, properties, delegates, and events. They also test LINQ, async/await, and garbage collection. Other topics include dependency injection, ASP.NET Core, and patterns like the generic repository.
Can I practice coding questions in the browser?
Yes. Coding questions include starter code in an in-browser editor, so you can write your solution without installing anything.
How often are the questions updated?
The question bank is reviewed regularly and updated to reflect current C# interview patterns.
Can I take a full mock interview?
Yes. Plaicer's mock technical interview walks you through a realistic 30 to 45 minute interview with AI-driven follow-up questions.
Do the questions cover .NET Core or .NET Framework?
Modern .NET (.NET 5 and later, formerly .NET Core). One question explains how it differs from the older .NET Framework.