Skip to content

OOP in C# Interview Questions for .NET Full Stack

25 OOP in C# questions with answers for .net full stack roles — 8 easy, 14 medium, 3 hard.

About OOP in C#

Object-oriented programming as used in real .NET code: classes, interfaces, abstract classes, inheritance, polymorphism, access modifiers, delegates and events. You will also revise SOLID principles and common design patterns such as Strategy, Factory, Repository and Singleton, which interviewers use to judge how you structure maintainable, testable enterprise applications.

Sheet progressStart practicing
3 QUESTIONS FREESign up to unlock the full question bank and track your progress.Unlock every question and answer, then continue practising company-wise and package-wise.
3 questions free Unlock the rest in seconds
01

What are the four pillars of object-oriented programming?

Save to ▾
Show answer
Encapsulation hides internal state behind methods and properties. Abstraction exposes only what the caller needs, using abstract classes and interfaces. Inheritance lets a class reuse and extend another class. Polymorphism lets one interface have many implementations, so code calls Pay() without knowing whether it is a card or UPI payment. Together they make code easier to change, test and reuse.
02

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

Save to ▾
Show answer
An abstract class can have fields, constructors, implemented and abstract members, and a class can inherit only one. An interface defines a contract; a class can implement many. Since C# 8, interfaces can have default method implementations but still no instance fields. Use an abstract class for shared state and base behaviour among closely related types, and interfaces for capabilities like IComparable or for dependency injection.
03

What is the difference between method overloading and method overriding?

Save to ▾
Show answer
Overloading means several methods with the same name but different parameter lists in the same class, resolved at compile time, for example Add(int, int) and Add(double, double). Overriding means a derived class provides a new implementation of a virtual or abstract base method with the same signature, resolved at runtime based on the actual object type. Overloading is compile-time polymorphism; overriding is runtime polymorphism.
04

What does the sealed keyword do?

Save to ▾
Show answer
A sealed class cannot be inherited, and a sealed override method cannot be overridden further in derived classes. Use it when a class is not designed for extension, such as a security-sensitive or immutable type; string is sealed for this reason. Sealing also lets the JIT devirtualise calls, giving small performance gains. Many teams seal classes by default and unseal only when inheritance is genuinely needed.
05

Show constructor chaining in C#.

Save to ▾
Show answer
public class Customer { public string Name { get; } public string City { get; } public Customer(string name) : this(name, "Unknown") { } public Customer(string name, string city) { Name = name; City = city; } } public class PremiumCustomer : Customer { public PremiumCustomer(string name) : base(name, "Delhi") { } } this() calls another constructor of the same class and base() calls the parent constructor, avoiding duplicated setup code.
06

What is the difference between compile-time and runtime polymorphism?

Save to ▾
Show answer
Compile-time, or static, polymorphism is resolved by the compiler, mainly through method overloading and operator overloading, and through generics. Runtime, or dynamic, polymorphism is resolved when the program runs, through virtual methods and interfaces: a Shape reference may call Circle.Area or Square.Area depending on the actual object. Runtime polymorphism is what makes plugin designs and dependency injection possible.
07

Show encapsulation using properties, including init-only and validation.

Save to ▾
Show answer
public class BankAccount { public string AccountNo { get; init; } = ""; public decimal Balance { get; private set; } public void Deposit(decimal amount) { if (amount <= 0) throw new ArgumentOutOfRangeException(nameof(amount)); Balance += amount; } } var acc = new BankAccount { AccountNo = "SB1001" }; Balance can only change through Deposit, and AccountNo can be set only during object creation.
08

What are partial classes and partial methods?

Save to ▾
Show answer
A partial class splits one class definition across multiple files, and the compiler merges them. It is used heavily with generated code: designers, EF Core scaffolding and source generators write one part while you write the other, so regeneration does not erase your code. Partial methods declare a signature in one part and an optional implementation in another; since C# 9 they can have return types and access modifiers if implemented.
09

You need to add a new method to a widely implemented interface without breaking existing classes. How can you do it?

OOP in C#Medium
Save to ▾
Show answer
Since C# 8, an interface can provide a method body. Classes implementing the interface get that behaviour without writing it, though they can override it. The main use is evolving a published interface: you can add a new member without breaking every existing implementation. The default method is only callable through the interface type, not the class, and overusing it blurs the line with abstract classes.
10

Explain the virtual, override and new keywords.

OOP in C#Medium
Save to ▾
Show answer
virtual marks a base method as replaceable. override in a derived class replaces it, so calls through a base reference run the derived version. new hides the base method instead: a call through a base reference still runs the base version, and only a derived-type reference sees the new one. Method hiding is usually a sign of a design problem, and the compiler warns when you hide without writing new.
11

Explain the access modifiers in C#, including protected internal and private protected.

OOP in C#Medium
Save to ▾
Show answer
public is accessible everywhere, private only inside the type, protected inside the type and derived types, and internal anywhere in the same assembly. protected internal means accessible from the same assembly or from derived types in any assembly. private protected is stricter: only derived types inside the same assembly. Class members default to private and top-level types default to internal. Use the narrowest modifier that works.
12

What is the difference between a static class and a singleton?

OOP in C#Medium
Save to ▾
Show answer
A static class cannot be instantiated, cannot implement interfaces and is initialised by the runtime; it suits stateless helpers like Math. A singleton is a normal class with exactly one instance, so it can implement interfaces, be passed as a parameter and be mocked in tests. In ASP.NET Core, you rarely write a singleton by hand; you register the class with AddSingleton and let the DI container manage its lifetime.
13

Explain the SOLID principles briefly.

OOP in C#Medium
Save to ▾
Show answer
Single Responsibility: a class has one reason to change. Open/Closed: extend behaviour without editing existing code. Liskov Substitution: derived types must work wherever the base type is expected. Interface Segregation: prefer small, focused interfaces over one fat interface. Dependency Inversion: depend on abstractions, not concrete classes. In ASP.NET Core, injecting IEmailSender into a controller instead of creating SmtpClient directly applies dependency inversion.
14

Show an example of the Dependency Inversion Principle in C#.

OOP in C#Medium
Save to ▾
Show answer
public interface INotifier { Task SendAsync(string to, string msg); } public class SmsNotifier : INotifier { public Task SendAsync(string to, string msg) => Task.CompletedTask; // call SMS API } public class OrderService(INotifier notifier) { public Task ConfirmAsync(Order o) => notifier.SendAsync(o.Phone, "Order placed"); } // Program.cs builder.Services.AddScoped<INotifier, SmsNotifier>(); OrderService depends on the abstraction, so you can swap to email or a mock without changing it.
15

A teammate created a deep inheritance chain Employee > Manager > SeniorManager > RegionalHead to add features. What would you suggest?

OOP in C#Medium
Save to ▾
Show answer
Deep hierarchies are fragile: a change in a base class ripples into every child, and behaviours that do not fit the tree get duplicated. I would suggest composition over inheritance. Keep a single Employee entity and give it composed parts such as a Role, an ApprovalPolicy and a list of Permissions, injected as interfaces. New behaviour then means a new policy class, not a new subclass, which is easier to test.
16

What is a delegate in C#?

OOP in C#Medium
Save to ▾
Show answer
A delegate is a type-safe reference to a method with a specific signature, similar to a function pointer but checked by the compiler. You can pass methods as parameters, store them and call them later. Delegates can be multicast, holding several methods that run in order. Lambdas, LINQ, events and callbacks are all built on delegates, and the built-in Func and Action types cover most needs.
17

How are events different from plain delegates?

OOP in C#Medium
Save to ▾
Show answer
An event is a delegate wrapped with restricted access. Outside the class, subscribers can only add or remove handlers with += and -=; they cannot invoke the event or overwrite the whole list with =. This protects the publisher. The standard pattern uses EventHandler<TEventArgs> with sender and args. Remember to unsubscribe long-lived subscriptions, otherwise the publisher keeps subscribers alive and causes memory leaks.
18

Show how Func, Action and Predicate are used.

OOP in C#Medium
Save to ▾
Show answer
Func<decimal, decimal> addGst = price => price * 1.18m; Action<string> log = msg => Console.WriteLine($"[LOG] {msg}"); Predicate<int> isAdult = age => age >= 18; decimal total = addGst(1000m); // 1180 log($"Total {total}"); bool ok = isAdult(21); // true Func returns a value (last type argument is the return type), Action returns void, and Predicate<T> returns bool. They save you from declaring custom delegate types.
19

Which design patterns do you commonly see in ASP.NET Core projects?

OOP in C#Medium
Save to ▾
Show answer
Dependency Injection is built in. The Repository and Unit of Work patterns wrap data access, although DbContext already implements them. Factory creates objects by type, for example IHttpClientFactory. Strategy swaps algorithms, such as different tax or discount rules, behind one interface. Options pattern binds configuration to classes. Middleware is a Chain of Responsibility, and Mediator libraries implement CQRS by sending commands to handlers.
20

What is the difference between a shallow copy and a deep copy?

OOP in C#Medium
Save to ▾
Show answer
A shallow copy duplicates the object but its reference fields still point to the same child objects; MemberwiseClone and record with-expressions do this. A deep copy duplicates the whole object graph, so changes to the copy never affect the original. Deep copies are usually written by hand or by serialising and deserialising. ICloneable is avoided because it does not say which kind of copy it returns.
21

Tell me about a time you refactored messy code that others depended on.

OOP in C#Medium
Save to ▾
Show answer
In my last project (Situation) an invoice module had one 900-line class with duplicated GST logic. My task was to add a new tax rule without breaking billing. I first wrote unit tests around current behaviour, then extracted tax rules into strategy classes and moved data access into a repository, merging in small pull requests. Result: the new rule took one day, and bugs in that module dropped noticeably the next quarter.
22

How do you explain good object-oriented design to a junior developer on your team?

OOP in C#Medium
Save to ▾
Show answer
I avoid theory first. I take a real piece of our code, like a controller that talks to the database directly, and pair with them to move logic into a service behind an interface, then write a unit test with a mock. Seeing how much easier testing becomes explains SOLID better than slides. I then review their next pull request with specific comments and point them to one or two good examples in our codebase.
23

A PaymentService has a large if-else on payment type (card, UPI, netbanking, wallet) and every new method means editing it. How do you refactor?

Save to ▾
Show answer
Apply the Strategy pattern with the Open/Closed principle. Define IPaymentProcessor with a Type property and ProcessAsync method, and create one class per method. Register all of them in DI, inject IEnumerable<IPaymentProcessor>, and pick the right one by type, possibly through a dictionary. Adding a new payment type is now a new class plus a registration, with no change to existing, tested code.
24

Write a thread-safe singleton in C#.

Save to ▾
Show answer
public sealed class AppConfig { private static readonly Lazy<AppConfig> _instance = new(() => new AppConfig()); public static AppConfig Instance => _instance.Value; private AppConfig() { // load settings once } } Lazy<T> is thread-safe by default and creates the object only on first access. The private constructor and sealed class prevent other instances. In ASP.NET Core, prefer AddSingleton.
25

Give an example of a Liskov Substitution Principle violation and how to fix it.

Save to ▾
Show answer
A classic case is Square inheriting Rectangle. Setting Width on a square also changes Height, so code that sets width 5 and height 4 and expects area 20 breaks. Another real case is a ReadOnlyRepository that inherits Repository and throws NotSupportedException on Save. The fix is to model shared behaviour with interfaces such as IShape or IReadRepository and IWriteRepository, so subclasses never weaken the contract.

Frequently asked questions

How important is OOP in C# in .NET Full Stack interviews?

Object-oriented programming as used in real .NET code: classes, interfaces, abstract classes, inheritance, polymorphism, access modifiers, delegates and events. You will also revise SOLID principles and common design patterns such as Strategy, Factory, Repository and Singleton, which interviewers use to judge how you structure maintainable, testable enterprise applications.

How should I use the OOP in C# sheet?

Go top to bottom — easy to hard. Answer before opening each answer, tick what you solved and save misses to Last-Minute Revision.