.NET (C#) Interview Questions and Answers
This document contains a collection of 50 interview questions related to .NET and the C# programming language, aimed at assessing candidates at various levels of expertise.
For more content like this be sure to join 10,500+ engineers to my .NET Pro Weekly Newsletter: https://stefandjokic.tech/?utm_source=github
These are only technical questions, it is not guaranteed that you will pass the interview if you know all the questions.
Basic
- What is .NET?
- Can you explain the Common Language Runtime (CLR)?
- What is the difference between managed and unmanaged code?
- Explain the basic structure of a C# program.
- What are Value Types and Reference Types in C#?
- What is garbage collection in .NET?
- Explain the concept of exception handling in C#.
- What are the different types of classes in C#?
- Can you describe what a namespace is and how it is used in C#?
- What is encapsulation?
Intermediate
- Explain polymorphism and its types in C#.
- What are delegates and how are they used in C#?
- Describe what LINQ is and give an example of where it might be used.
- What is the difference between an abstract class and an interface?
- How do you manage memory in .NET applications?
- Explain the concept of threading in .NET.
- What is async/await and how does it work?
- Describe the Entity Framework and its advantages.
- What are extension methods and where would you use them?
- How do you handle exceptions in a method that returns a Task?
Advanced
- What is reflection in .NET and how would you use it?
- Can you explain the concept of middleware in ASP.NET Core?
- Describe the Dependency Injection (DI) pattern and how it's implemented in .NET Core.
- What is the purpose of the .NET Standard?
- Explain the differences between .NET Core, .NET Framework, and Xamarin.
- How does garbage collection work in .NET and how can you optimize it?
- What are attributes in C# and how can they be used?
- Can you describe the process of code compilation in .NET?
- What is the Global Assembly Cache (GAC) and when should it be used?
- How would you secure a web application in ASP.NET Core?
Framework-Specific
- What is MVC (Model-View-Controller)?
- Can you explain the difference between Razor Pages and MVC in ASP.NET Core?
- How do you perform validations in ASP.NET Core?
- Describe SignalR and its use cases.
- What are the benefits of using Blazor over traditional web technologies?
- How do you implement Web API versioning in ASP.NET Core?
- Explain the role of IApplicationBuilder in ASP.NET Core.
- What are Areas in ASP.NET Core and how do you use them?
- How do you manage sessions in ASP.NET Core applications?
- Describe how to implement caching in ASP.NET Core.
Testing & Best Practices
-
What is Unit Testing in .NET?
-
How do you mock dependencies in unit tests using .NET?
-
Can you explain SOLID principles?
-
What is Continuous Integration/Continuous Deployment (CI/CD) and how does it apply to .NET development?
-
How do you ensure your C# code is secure?
-
What are some common performance issues in .NET applications and how do you address them?
-
Describe the Repository pattern and its benefits.
-
How do you handle database migrations in Entity Framework?
-
What tools do you use for debugging and profiling .NET applications?
-
How do you stay updated with the latest .NET technologies and practices?
Basic
1. What is .NET?
Answer: .NET is a comprehensive development platform used for building a wide variety of applications, including web, mobile, desktop, and gaming. It supports multiple programming languages, such as C#, F#, and Visual Basic. .NET provides a large class library called Framework Class Library (FCL) and runs on a Common Language Runtime (CLR) which offers services like memory management, security, and exception handling.
2. Can you explain the Common Language Runtime (CLR)?
Answer: The CLR is a virtual machine component of the .NET framework that manages the execution of .NET programs. It provides important services such as memory management, type safety, exception handling, garbage collection, and thread management. The CLR converts Intermediate Language (IL) code into native machine code through a process called Just-In-Time (JIT) compilation. This ensures that .NET applications can run on any device or platform that supports the .NET framework.
3. What is the difference between managed and unmanaged code?
Answer: Managed code is executed by the CLR, which provides services like garbage collection, exception handling, and type checking. It's called "managed" because the CLR manages a lot of the functionalities that developers would otherwise need to implement themselves. Unmanaged code, on the other hand, is executed directly by the operating system, and all memory allocation, type safety, and security must be handled by the programmer. Examples of unmanaged code include applications written in C or C++.
4. Explain the basic structure of a C# program.
Answer: A basic C# program consists of the following elements:
- Namespace declaration: A way to organize code and control the scope of classes and methods in larger projects.
- Class declaration: Defines a new type with data members (fields, properties) and function members (methods, constructors).
- Main method: The entry point for the program where execution begins and ends.
- Statements and expressions: Perform actions with variables, calling methods, looping through collections, etc.
using System;
namespace HelloWorld
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}
5. What are Value Types and Reference Types in C#?
Answer: In C#, data types are divided into two categories: Value Types and Reference Types. This distinction affects how values are stored and manipulated within memory.
-
Value Types: Store data directly and are allocated on the stack. This means that when you assign one value type to another, a direct copy of the value is created. Basic data types (
int
,double
,bool
, etc.) and structs are examples of value types. Operations on value types are generally faster due to stack allocation. -
Reference Types: Store a reference (or pointer) to the actual data, which is allocated on the heap. When you assign one reference type to another, both refer to the same object in memory; changes made through one reference are reflected in the other. Classes, arrays, delegates, and strings are examples of reference types.
Here's a simple example to illustrate the difference:
// Value type example
int a = 10;
int b = a;
b = 20;
Console.WriteLine(a); // Output: 10
Console.WriteLine(b); // Output: 20
// Reference type example
var list1 = new List<int> { 1, 2, 3 };
var list2 = list1;
list2.Add(4);
Console.WriteLine(list1.Count); // Output: 4
Console.WriteLine(list2.Count); // Output: 4
In the value type example, changing b does not affect a because b is a separate copy. In the reference type example, list2 is not a separate copy; it's another reference to the same list object as list1, so changes made through list2 are visible when accessing list1.
6. What is garbage collection in .NET?
Answer: Garbage collection (GC) in .NET is an automatic memory management feature that frees up memory used by objects that are no longer accessible in the program. It eliminates the need for developers to manually release memory, thereby reducing memory leaks and other memory-related errors. The GC operates on a separate thread and works in three phases: marking, relocating, and compacting. During the marking phase, it identifies which objects in the heap are still in use. During the relocating phase, it updates the references to objects that will be compacted. Finally, during the compacting phase, it reclaims the space occupied by the garbage objects and compacts the remaining objects to make memory allocation more efficient.
7. Explain the concept of exception handling in C#.
Answer: Exception handling in C# is a mechanism to handle runtime errors, allowing a program to continue running or fail gracefully instead of crashing. It is done using the try, catch, and finally blocks. The try block contains code that might throw an exception, while catch blocks are used to handle the exception. The finally block contains code that is executed whether an exception is thrown or not, often for cleanup purposes.
try {
// Code that may cause an exception
int divide = 10 / 0;
}
catch (DivideByZeroException ex) {
// Code to handle the exception
Console.WriteLine("Cannot divide by zero. Please try again.");
}
finally {
// Code that executes after try/catch, regardless of an exception
Console.WriteLine("Operation completed.");
}
8. What are the different types of classes in C#?
Answer: In C#, classes can be categorized based on their functionality and accessibility:
- Static classes: Cannot be instantiated and can only contain static members.
- Sealed classes: Cannot be inherited from.
- Abstract classes: Cannot be instantiated and are meant to be inherited from.
- Partial classes: Allow the splitting of a class definition across multiple files.
- Generic classes: Allow the definition of classes with placeholders for the type of its fields, methods, parameters, etc.
Each type serves different purposes in the context of object-oriented programming and design patterns.
9. Can you describe what a namespace is and how it is used in C#?
Answer: A namespace in C# is used to organize code into a hierarchical structure. It allows the grouping of logically related classes, structs, interfaces, enums, and delegates. Namespaces help avoid naming conflicts by qualifying the uniqueness of each type. For example, the System
namespace in .NET includes classes for basic system operations, such as console input/output, file reading/writing, and data manipulation.
using System;
namespace MyApplication
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
}
}
}
In this example, the System namespace is used to access the Console class, and MyApplication is a custom namespace for organizing the application's code. Namespaces are essential for managing the scope of names in larger programming projects to avoid name collisions.
10. What is encapsulation?
Answer: Encapsulation is a fundamental principle of object-oriented programming (OOP) that involves bundling the data (attributes) and methods (operations) that operate on the data into a single unit, or class, and restricting access to the internals of that class. This is typically achieved through the use of access modifiers such as private
, public
, protected
, and internal
. Encapsulation helps to protect an object's internal state from unauthorized access and modification by external code, promoting data integrity and security.
Encapsulation allows the internal representation of an object to be hidden from the outside, only allowing access through a public interface. This concept is also known as data hiding. By controlling how data is accessed and modified, encapsulation helps to reduce complexity and increase reusability of code.
Here is a simple example demonstrating encapsulation in C#:
public class Person
{
private string name; // Private field, encapsulated data
public string Name // Public property, access to the name field
{
get { return name; }
set { name = value; }
}
public Person(string name) // Constructor
{
this.name = name;
}
}
class Program
{
static void Main(string[] args)
{
Person person = new Person("John");
Console.WriteLine(person.Name); // Accessing name through a public property
}
}
In this example, the name field of the Person class is encapsulated and only accessible via the Name property. This approach allows the Person class to control how the name field is accessed and modified, ensuring that any rules or validations about the data can be applied within the class itself.
11. Explain polymorphism and its types in C#.
Answer: Polymorphism is a core concept in object-oriented programming (OOP) that allows objects to be treated as instances of their parent class rather than their actual derived class. This enables methods to perform different tasks based on the object that invokes them, enhancing flexibility and enabling code reusability. In C#, polymorphism can be implemented in two ways: static (compile-time) polymorphism and dynamic (runtime) polymorphism.
-
Static Polymorphism: Achieved through method overloading and operator overloading. It allows multiple methods or operators with the same name but different parameters to coexist, with the specific method or operator being invoked determined at compile time based on the arguments passed.
-
Dynamic Polymorphism: Achieved through method overriding. It allows a method in a derived class to have the same name and signature as a method in its base class, but with different implementation details. The method that gets executed is determined at runtime, depending on the type of the object.
Here's an example demonstrating both types of polymorphism in C#:
// Static Polymorphism (Method Overloading)
public class Calculator
{
public int Add(int a, int b)
{
return a + b;
}
public int Add(int a, int b, int c)
{
return a + b + c;
}
}
// Dynamic Polymorphism (Method Overriding)
public class Animal
{
public virtual void Speak()
{
Console.WriteLine("The animal speaks");
}
}
public class Dog : Animal
{
public override void Speak()
{
Console.WriteLine("Dog barks");
}
}
class Program
{
static void Main(string[] args)
{
Calculator calc = new Calculator();
Console.WriteLine(calc.Add(2, 3)); // Calls the first Add method
Console.WriteLine(calc.Add(2, 3, 4)); // Calls the second Add method
Animal myAnimal = new Animal();
myAnimal.Speak(); // Output: The animal speaks
Dog myDog = new Dog();
myDog.Speak(); // Output: Dog barks
Animal mySecondAnimal = new Dog();
mySecondAnimal.Speak(); // Output: Dog barks, demonstrating dynamic polymorphism
}
}
In the example above, the Calculator class demonstrates static polymorphism through method overloading, allowing the Add method to be called with different numbers of parameters. The Animal and Dog classes illustrate dynamic polymorphism, where the Speak method in the Dog class overrides the Speak method in its base class, Animal. The type of polymorphism used depends on the object reference at runtime, showcasing polymorphism's flexibility in OOP.
12. What are delegates and how are they used in C#?
Answer: Delegates in C# are type-safe function pointers or references to methods with a specific parameter list and return type. They allow methods to be passed as parameters, stored in variables, and returned by other methods, which enables flexible and extensible programming designs such as event handling and callback methods. Delegates are particularly useful in implementing the observer pattern and designing frameworks or components that need to notify other objects about events or changes without knowing the specifics of those objects.
There are three main types of delegates in C#:
- Single-cast delegates: Point to a single method at a time.
- Multicast delegates: Can point to multiple methods on a single invocation list.
- Anonymous methods/Lambda expressions: Allow inline methods or lambda expressions to be used wherever a delegate is expected.
Here is an example demonstrating the use of delegates in C#:
public delegate void Operation(int num);
class Program
{
static void Main(string[] args)
{
Operation op = Double;
op(5); // Output: 10
op = Triple;
op(5); // Output: 15
// Multicast delegate
op = Double;
op += Triple; // Combines Double and Triple methods
op(5); // Output: 10 followed by 15
}
static void Double(int num)
{
Console.WriteLine($"{num} * 2 = {num * 2}");
}
static void Triple(int num)
{
Console.WriteLine($"{num} * 3 = {num * 3}");
}
}
In this example, the Operation delegate is defined to point to any method that accepts an int and returns void. Initially, op is set to the Double method, demonstrating a single-cast delegate. It is then reassigned to the Triple method, and finally, it is used as a multicast delegate to call both Double and Triple methods in sequence. This demonstrates how delegates in C# provide a flexible mechanism for method invocation and can be used to implement event handlers and callbacks.
13. Describe what LINQ is and give an example of where it might be used.
Answer: LINQ (Language Integrated Query) is a powerful feature in C# that allows developers to write expressive, readable code to query and manipulate data. It provides a uniform way to query various data sources, such as collections in memory, databases (via LINQ to SQL, LINQ to Entities), XML documents (LINQ to XML), and more. LINQ queries offer three main benefits: they are strongly typed, offer compile-time checking, and support IntelliSense, which enhances developer productivity and code maintainability.
LINQ can be used in a variety of scenarios, including filtering, sorting, and grouping data. It supports both method syntax and query syntax, providing flexibility in how queries are expressed.
Here is a simple example demonstrating LINQ with a list of integers:
using System;
using System.Linq;
using System.Collections.Generic;
class Program
{
static void Main(string[] args)
{
List<int> numbers = new List<int> { 1, 2, 3,