C# Interview Questions

I have collected C# interview questions and answers for fresh developers, senior developers, and mid-level developers.
C# interview questions for Beginners
Question: What is polymorphism in c#
Answer: Polymorphism is the ability of an object to take on many forms. In C#, polymorphism is achieved through inheritance and interfaces.
Inheritance allows derived classes to inherit properties and methods from their base classes. This allows objects of the derived class to be used wherever objects of the base class are expected. For example, if we have a base class called “Animal” and a derived class called “Dog”, we can use a “Dog” object anywhere we would use an “Animal” object.
public class Animal
{
public virtual void MakeSound()
{
Console.WriteLine("The animal makes a sound");
}
}
public class Dog : Animal
{
public override void MakeSound()
{
Console.WriteLine("The dog barks");
}
}
Animal animal = new Dog(); // Creating an instance of derived class
animal.MakeSound(); // Output: "The dog barks"
In this example, the “Dog” class is a derived class of the “Animal” class. It overrides the “MakeSound” method of the base class and provides its own implementation. When we create an instance of the “Dog” class and assign it to an “Animal” variable, we can call the “MakeSound” method and the implementation of the “Dog” class is used instead of the implementation of the “Animal” class.
Interfaces provide another way to achieve polymorphism in C#. An interface defines a set of methods and properties that a class must implement. This allows objects of different classes to be treated as the same type if they implement the same interface
Question: what is boxing & unboxing in c#?
Answer: In C#, boxing, and unboxing are mechanisms used to convert value types (such as int, double, and bool) to reference types (such as an object) and vice versa. Here’s a brief explanation of each:
Boxing: Boxing is the process of converting a value type to a reference type. When you box a value type, a new object is created on the heap and the value of the value type is copied into that object. The original value type variable is now a reference to the newly created object.
Example:
int i = 10; // value type
object obj = i; // boxing - converting i to a reference type
Unboxing: Unboxing is the process of converting a reference type back to a value type. When you unbox a reference type, the value of the boxed value type is copied back into a new value type variable. The reference type variable now refers to this new value type variable.
int i = 10; // value type
object obj = i; // boxing - converting i to a reference type
int j = (int)obj; // unboxing - converting obj back to a value type
Note that unboxing can only be done if the original boxed value was of the correct value type. If not, an InvalidCastException will be thrown at runtime.
Boxing and unboxing can have performance implications, particularly if they are done frequently in performance-critical code. This is because creating objects on the heap can be expensive in terms of memory allocation and garbage collection. Therefore, it’s generally a good idea to avoid boxing and unboxing unless it’s absolutely necessary.
Senior developers
Question: what is the SOLID principle in C#
Answer: SOLID is a set of principles that guide software development and design, aimed at producing code that is more modular, flexible, and maintainable. The acronym SOLID stands for:
- S – Single Responsibility Principle (SRP)
- O – Open/Closed Principle (OCP)
- L – Liskov Substitution Principle (LSP)
- I – Interface Segregation Principle (ISP)
- D – Dependency Inversion Principle (DIP)
Here’s a brief overview of each principle:
- Single Responsibility Principle (SRP): A class should have only one reason to change. In other words, a class should have only one responsibility or job to do. This principle promotes the idea of creating smaller, more focused classes that are easier to test, maintain, and extend.
- Open/Closed Principle (OCP): A class should be open for extension but closed for modification. This principle encourages developers to design their classes in a way that allows them to add new functionality without modifying the existing code. This can be achieved by using inheritance, composition, or other design patterns.
- Liskov Substitution Principle (LSP): Subtypes should be substitutable for their base types. This principle ensures that a subclass can be used in place of its parent class without any unexpected behavior. In other words, a subclass should adhere to the same contract as its parent class.
- Interface Segregation Principle (ISP): A client should not be forced to depend on interfaces it does not use. This principle encourages developers to create smaller, more specific interfaces that are tailored to the needs of the client. This helps to avoid unnecessary dependencies and makes the code more modular.
- Dependency Inversion Principle (DIP): High-level modules should not depend on low-level modules. Both should depend on abstractions. This principle promotes the use of interfaces and abstractions to reduce coupling between components. It encourages the use of dependency injection, which allows components to be easily replaced or modified without affecting the rest of the system.
By following the SOLID principles, developers can create code that is easier to understand, test, and maintain. The SOLID principles promote modularity, flexibility, and extensibility, which are important qualities for any software system.