Top 25 interview questions for C#

Here are elaborated answers to the top 25 C# interview questions with comprehensive explanations and relevant examples:

1. What is C# and its key features?

C# is a modern, object-oriented, type-safe programming language developed by Microsoft as part of the .NET framework. It is designed to combine the computing power of C++ with the ease of use of Visual Basic. C# provides a robust framework for building a wide range of applications, from web services to sophisticated desktop applications.

Key Features:

  • Object-Oriented: Supports concepts like encapsulation, inheritance, and polymorphism, making it easier to manage and maintain complex systems.
  • Type-Safe: Prevents type errors, ensuring that objects are always used in compatible ways.
  • Managed Code: Runs under the Common Language Runtime (CLR), providing services like garbage collection, exception handling, and resource management.
  • Interoperability: Can interact with other languages and components, especially those written in other .NET languages.
  • Versatility: Used for developing desktop applications, web applications, services, and games.
  • Memory Management: Automatic garbage collection relieves developers from manual memory management.
  • Component-Oriented: Facilitates component-based development, where applications are built from reusable components.

2. Explain the difference between value types and reference types.

Value Types:

  • Definition: Store data directly in their own memory location.
  • Examples: int, float, bool, and structs.
  • Behavior: When a value type is assigned to another value type, a copy of the value is made.
  • Memory: Allocated on the stack, providing better performance for small data types.

Example:

int age = 30;
int anotherAge = age;  // anotherAge is a copy of age
anotherAge = 35;
Console.WriteLine(age);  // Outputs 30
Console.WriteLine(anotherAge);  // Outputs 35

Reference Types:

  • Definition: Store a reference (or address) to the actual data in memory.
  • Examples: string, arrays, classes, and objects.
  • Behavior: When a reference type is assigned to another, both variables reference the same memory location.
  • Memory: Allocated on the heap, suitable for larger data structures.

Example:

string parkName = "Mount Rainier";
string anotherPark = parkName;  // anotherPark references the same string
anotherPark = "Olympic";
Console.WriteLine(parkName);  // Outputs "Mount Rainier"
Console.WriteLine(anotherPark);  // Outputs "Olympic"

3. What are managed and unmanaged codes?

Managed Code:

  • Definition: Runs under the control of the CLR, benefiting from features like garbage collection, type safety, and exception handling.
  • Advantages: Provides memory management, type safety, and security services.

Example:

using System;

namespace ManagedCodeExample
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello, managed world!");
        }
    }
}

Unmanaged Code:

  • Definition: Runs outside the control of the CLR, typically written in languages like C or C++. It requires explicit memory management.
  • Disadvantages: Higher risk of memory leaks and security vulnerabilities due to lack of CLR services.

Example:

// Example in C (unmanaged code)
#include <stdio.h>

int main()
{
    printf("Hello, unmanaged world!");
    return 0;
}

4. Define an abstract class and its use case.

Abstract Class:

  • Definition: A class that cannot be instantiated and is meant to be a base class for other classes. It can contain abstract methods (without implementation) and concrete methods (with implementation).
  • Use Case: Useful when creating a base class that should not be instantiated but needs to share common functionality with derived classes.

Example:

public abstract class NationalPark
{
    public string Name { get; set; }
    public string Location { get; set; }

    public abstract void DisplayInfo();  // Abstract method

    public void ShowLocation()  // Concrete method
    {
        Console.WriteLine($"Location: {Location}");
    }
}

public class WashingtonNationalPark : NationalPark
{
    public override void DisplayInfo()
    {
        Console.WriteLine($"Park: {Name}, Location: {Location}");
    }
}

In this example, NationalPark is an abstract class with an abstract method DisplayInfo and a concrete method ShowLocation. WashingtonNationalPark inherits from NationalPark and provides an implementation for DisplayInfo.

5. What is an interface in C#?

Interface:

  • Definition: A contract that defines a set of methods, properties, events, or indexers without implementation. Implementing classes must provide the method definitions.
  • Use Case: Useful for defining capabilities that can be shared among different classes, promoting loose coupling and easier unit testing.

Example:

public interface INationalPark
{
    string Name { get; set; }
    void DisplayInfo();
}

public class OlympicNationalPark : INationalPark
{
    public string Name { get; set; }

    public void DisplayInfo()
    {
        Console.WriteLine($"Park: {Name}");
    }
}

In this example, INationalPark is an interface with a property Name and a method DisplayInfo. OlympicNationalPark implements this interface, providing the actual method definition.

6. Explain the concept of polymorphism.

Polymorphism:

  • Definition: The ability of different objects to be treated as instances of the same class through a common interface. It allows methods to do different things based on the object it is acting upon.
  • Types:
  • Method Overriding (Runtime Polymorphism): Allows a derived class to provide a specific implementation of a method defined in its base class.
  • Method Overloading (Compile-Time Polymorphism): Allows creating multiple methods with the same name but different parameters in the same class.

Method Overloading Example:

public class Park
{
    public void Visit(string parkName)
    {
        Console.WriteLine($"Visiting {parkName}");
    }

    public void Visit(string parkName, int days)
    {
        Console.WriteLine($"Visiting {parkName} for {days} days");
    }
}

Method Overriding Example:

public class NationalPark
{
    public virtual void Visit()
    {
        Console.WriteLine("Visiting a national park");
    }
}

public class OlympicPark : NationalPark
{
    public override void Visit()
    {
        Console.WriteLine("Visiting Olympic National Park");
    }
}

7. What is method overloading?

Method Overloading:

  • Definition: Defining multiple methods with the same name but different signatures (parameter lists) in the same class. It allows methods to handle different types or numbers of inputs.
  • Advantages: Improves code readability and allows flexibility in method usage.

Example:

public class Park
{
    public void Info(string name)
    {
        Console.WriteLine($"Park Name: {name}");
    }

    public void Info(string name, string location)
    {
        Console.WriteLine($"Park Name: {name}, Location: {location}");
    }

    public void Info(string name, string location, int size)
    {
        Console.WriteLine($"Park Name: {name}, Location: {location}, Size: {size} acres");
    }
}

In this example, the Info method is overloaded with different parameter lists, allowing it to handle different sets of information about a park.

8. Describe method overriding.

Method Overriding:

  • Definition: Allows a derived class to provide a specific implementation of a method defined in its base class. It is achieved using the override keyword.
  • Use Case: Useful when the base class provides a general implementation that needs to be customized in derived classes.

Example:

public class NationalPark
{
    public virtual void Visit()
    {
        Console.WriteLine("Visiting a national park");
    }
}

public class MountRainier : NationalPark
{
    public override void Visit()
    {
        Console.WriteLine("Visiting Mount Rainier National Park");
    }
}

In this example, MountRainier overrides the Visit method from the NationalPark class to provide a specific implementation.

9. What are sealed classes?

Sealed Class:

  • Definition: A class that cannot be inherited. It is marked with the sealed keyword.
  • Use Case: Useful when you want to restrict the inheritance hierarchy to avoid further derivation and ensure that the class’s behavior remains unchanged.

Example:

public sealed class SealedPark
{
    public string Name { get; set; }
    public void DisplayInfo()
    {
        Console.WriteLine($"Park Name: {Name}");
    }
}

// This will cause a compile-time error
// public class DerivedPark : SealedPark
// {
// }

In this example, SealedPark is a sealed class, and any attempt to inherit from it will result in a compile-time error.

10. Explain the difference between an array and an ArrayList.

Array:

  • Definition: A fixed-size collection of elements of the same type.
  • Advantages: Provides better performance and type safety for a known fixed

-size collection.

  • Examples: int[], string[].
  • Syntax: Declared with a fixed size at compile time.
  • Memory: Allocated on the stack for small arrays, or the heap for large arrays.

Example:

string[] parks = new string[] { "Olympic", "Mount Rainier", "North Cascades" };
Console.WriteLine(parks[0]);  // Outputs "Olympic"

ArrayList:

  • Definition: A dynamic-size collection of elements that can store items of any type.
  • Advantages: Flexible size, can store a mix of data types.
  • Syntax: Declared without a fixed size, can grow or shrink as needed.
  • Memory: Always allocated on the heap.

Example:

using System.Collections;

ArrayList parkList = new ArrayList();
parkList.Add("Olympic");
parkList.Add(123);  // Mixed types allowed
Console.WriteLine(parkList[0]);  // Outputs "Olympic"
Console.WriteLine(parkList[1]);  // Outputs 123

11. How do you implement thread safety in C#?

Thread Safety: Ensuring that shared resources are accessed and modified safely when multiple threads are involved.

Methods to Achieve Thread Safety:

  • Locks: Using the lock statement to ensure that only one thread can enter a critical section at a time.
  private static readonly object _lock = new object();

  public void VisitPark()
  {
      lock (_lock)
      {
          // Critical section
          Console.WriteLine("Visiting the park safely");
      }
  }
  • Monitor Class: Provides more control over the locking mechanism.
  private static readonly object _lock = new object();

  public void VisitPark()
  {
      Monitor.Enter(_lock);
      try
      {
          // Critical section
          Console.WriteLine("Visiting the park safely");
      }
      finally
      {
          Monitor.Exit(_lock);
      }
  }
  • Interlocked Class: Provides atomic operations for variables, ensuring thread safety without explicit locking.
  private int visitorCount;

  public void IncrementVisitorCount()
  {
      Interlocked.Increment(ref visitorCount);
  }
  • Concurrent Collections: Collections like ConcurrentDictionary and BlockingCollection provide built-in thread-safety mechanisms.
  ConcurrentDictionary<int, string> parkVisitors = new ConcurrentDictionary<int, string>();
  parkVisitors.TryAdd(1, "Visitor1");

12. What are delegates and their types in C#?

Delegates: Type-safe function pointers that define a method signature and can reference methods with matching signatures.

Types of Delegates:

  • Singlecast Delegate: Points to a single method.
  public delegate void ParkVisit(string parkName);

  public class Park
  {
      public void Visit(string name)
      {
          Console.WriteLine($"Visiting {name}");
      }
  }

  ParkVisit visitDelegate = new ParkVisit(new Park().Visit);
  visitDelegate("Mount Rainier");
  • Multicast Delegate: Points to multiple methods, invoking them in sequence.
  public delegate void ParkVisit(string parkName);

  public class Park
  {
      public void Visit(string name)
      {
          Console.WriteLine($"Visiting {name}");
      }
  }

  ParkVisit visitDelegate = new ParkVisit(new Park().Visit);
  visitDelegate += new Park().Visit;
  visitDelegate("Olympic");
  • Generic Delegates: Predefined delegates in the .NET framework like Func, Action, and Predicate.
  Func<string, string> parkFunc = parkName => $"Visiting {parkName}";
  Action<string> parkAction = parkName => Console.WriteLine($"Visiting {parkName}");
  Predicate<string> isParkLongName = parkName => parkName.Length > 10;

13. What are events and event delegates in C#?

Events: Mechanism to provide notifications when something of interest occurs. Events are based on delegates and provide a way to execute a method in response to an event.

Event Delegates:

Example:

public delegate void ParkVisitHandler(string parkName);

public class Park
{
    public event ParkVisitHandler OnParkVisit;

    public void Visit(string name)
    {
        OnParkVisit?.Invoke(name);
    }
}

public class Visitor
{
    public void RespondToVisit(string parkName)
    {
        Console.WriteLine($"Responding to visit to {parkName}");
    }
}

// Usage
Park park = new Park();
Visitor visitor = new Visitor();
park.OnParkVisit += visitor.RespondToVisit;
park.Visit("Mount Rainier");

In this example, the OnParkVisit event is triggered when the Visit method is called, and the Visitor class responds to this event.

14. What is LINQ and provide an example.

LINQ (Language Integrated Query): A powerful feature that allows querying data from different sources (like arrays, collections, XML, databases) directly within the C# language. It provides a unified model for querying and manipulating data, making the code more readable and maintainable.

Example:

using System;
using System.Collections.Generic;
using System.Linq;

public class NationalPark
{
    public string Name { get; set; }
    public string State { get; set; }
}

public class Program
{
    public static void Main()
    {
        List<NationalPark> parks = new List<NationalPark>
        {
            new NationalPark { Name = "Mount Rainier", State = "Washington" },
            new NationalPark { Name = "Olympic", State = "Washington" },
            new NationalPark { Name = "North Cascades", State = "Washington" },
            new NationalPark { Name = "Yellowstone", State = "Wyoming" }
        };

        var washingtonParks = from park in parks
                              where park.State == "Washington"
                              select park.Name;

        Console.WriteLine("National Parks in Washington:");
        foreach (var park in washingtonParks)
        {
            Console.WriteLine(park);
        }
    }
}

In this example, the LINQ query selects the names of national parks located in Washington state from a list of parks.

15. Explain the difference between System.String and System.Text.StringBuilder.

System.String:

  • Definition: Immutable, meaning once created, it cannot be changed. Each modification creates a new string, which can be inefficient for large or numerous string operations.
  • Use Case: Suitable for situations where string immutability is needed, such as fixed messages, labels, and keys.

Example:

string parkName = "Mount Rainier";
parkName += " National Park";  // Creates a new string
Console.WriteLine(parkName);  // Outputs "Mount Rainier National Park"

System.Text.StringBuilder:

  • Definition: Mutable, designed for situations where you need to perform repeated modifications to a string, improving performance and reducing memory overhead.
  • Use Case: Suitable for scenarios involving extensive string manipulation, such as building dynamic strings from user input or large datasets.

Example:

StringBuilder parkName = new StringBuilder("Mount Rainier");
parkName.Append(" National Park");
Console.WriteLine(parkName.ToString());  // Outputs "Mount Rainier National Park"

16. What are the differences between Finalize() and Dispose() methods?

Dispose():

  • Definition: Called explicitly to release unmanaged resources. It is part of the IDisposable interface and provides a way to deterministically release resources.
  • Use Case: When you need to release resources like file handles, database connections, or memory allocated from unmanaged code.
  • Implementation: Ensures that the resource is released immediately.

Example:

public class ParkResource : IDisposable
{
    public void Dispose()
    {
        // Release unmanaged resources
        GC.SuppressFinalize(this);
    }
}

Finalize():

  • Definition: Called by the garbage collector just before the object is reclaimed. It is used to clean up unmanaged resources if Dispose() was not called.
  • Use Case: Provides a safety net for releasing resources if Dispose() is not called. Less predictable than Dispose() as it depends on the garbage collection process.
  • Implementation: Should be used to release resources as a last resort.

Example:

public class ParkResource
{
    ~ParkResource()
    {
        // Finalizer code to release unmanaged resources
    }
}

17. What are generics in C#?

Generics: Allow defining classes, methods, and data structures with a placeholder for the type of data they store. This promotes code reusability, type safety, and performance.

Benefits:

  • Type Safety: Ensures that only the specified type is used, preventing runtime errors.
  • Code Reusability: Write a generic class or method once and use it with different data types.
  • Performance: Eliminates the need for boxing/unboxing and type casting.

Example:

public class Park<T>
{
    public T Name { get; set; }
}

public class Program
{
    public static void Main()
    {
        Park<string> park = new Park<string> { Name = "Mount Rainier" };
        Console.WriteLine(park.Name);  // Outputs "Mount Rainier"
    }
}

In this example, Park is a generic class that can store data of any type. In this case, it stores a string type representing the park name.

18. Explain covariance and contravariance in C#.

Covariance:

  • Definition: Allows a method to return a more derived type than specified by the generic parameter. It is applicable in method return types or read-only fields.
  • Use Case: Provides flexibility in returning derived types from methods.
IEnumerable<object> objects = new List<string>();  // Covariance allows this assignment

Contravariance:

  • Definition: Allows a method to accept parameters of a more generic type than specified. It is applicable in method input parameters.
  • Use Case: Provides flexibility in accepting base types as method parameters.
Action<string> stringAction = s => Console.WriteLine(s);
Action<object> objectAction = stringAction;  // Contravariance allows this assignment

19. What is reflection in C# and its use case?

Reflection: Allows inspecting and interacting with metadata about assemblies, modules, and types at runtime. It is useful for dynamic type creation, method invocation, and attribute inspection.

Use Case: Reflection is commonly used for:

  • Dynamic type instantiation
  • Accessing private members
  • Runtime type discovery
  • Building dynamic and extensible applications
using System;
using System.Reflection;

public class Park
{
    public void DisplayInfo()
    {
        Console.WriteLine("National Park Information");
    }
}

public class Program
{
    public static void Main()
    {
        Type type = typeof(Park);
        MethodInfo method = type.GetMethod("DisplayInfo");
        object obj = Activator.CreateInstance(type);
        method.Invoke(obj, null);
    }
}

In this example, reflection is used to get the method info and invoke it dynamically.

20. How do you handle exceptions in C#?

Exception Handling: Ensuring that code can handle unexpected conditions gracefully using try, catch, and finally blocks.

public class ParkVisitor
{
    public void Visit(string parkName)
    {
        try
        {
            if (string.IsNullOrEmpty(parkName))
                throw new ArgumentNullException(nameof(parkName), "Park name cannot be null or empty");

            Console.WriteLine($"Visiting {parkName}");
        }
        catch (ArgumentNullException ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
        }
        finally
        {
            Console.WriteLine("End of visit.");
        }
    }
}

In this example, a try block contains code that might throw an exception, a catch block handles the exception, and a finally block contains code that will run regardless of whether an exception was thrown or not.

21. What is the difference between readonly and const?

const:

  • Definition: Compile-time constant. Must be assigned at declaration and cannot be changed.
  • Use Case: Suitable for values that are known at compile-time and will never change.
  • Example: public const string ParkType = “National Park”;

readonly:

  • Definition: Runtime constant. Can be assigned in the declaration or constructor and cannot be changed afterwards.
  • Use Case: Suitable for values that are assigned at runtime and should not change after being set.
public readonly string ParkName;

public Park(string name)
{
    ParkName = name;
}

What are partial classes?

Partial Classes: Allow splitting the definition of a class across multiple files. All parts are combined into a single class during compilation.

Use Case: Useful for organizing code, especially for large classes, and when working in team environments where multiple developers might work on the same class.

// ParkPart1.cs
public partial class Park
{
    public string Name { get; set; }
}

// ParkPart2.cs
public partial class Park
{
    public string Location { get; set; }
}

In this example, the Park class is split into two parts, but they are combined into a single class during compilation.

23. What is async and await in C#?

async and await: Keywords used to write asynchronous code more easily, helping maintain the responsiveness of an application by allowing asynchronous operations without blocking the main thread.

Use Case: Useful for performing I/O-bound or CPU-bound operations without blocking the UI or main thread, such as file I/O, network calls, or long-running calculations.

public async Task VisitParkAsync()
{
    await Task.Run(() => 
    {
        // Simulate a long-running operation
        Thread.Sleep(3000);
        Console.WriteLine("Visited park asynchronously");
    });
}

In this example, VisitParkAsync performs a long-running operation without blocking the calling thread.

24. Explain the use of the IDisposable interface.

IDisposable: Interface that provides a mechanism for releasing unmanaged resources deterministically. It contains a single method, Dispose(), which is called to free resources.

Use Case: Essential for classes that use unmanaged resources, such as file handles, database connections, or memory allocated from unmanaged code.

public class ParkResource : IDisposable
{
    private bool disposed = false;

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                // Free managed resources
            }
            // Free unmanaged resources
            disposed = true;
        }
    }

    ~ParkResource()
    {
        Dispose(false);
    }
}

In this example, ParkResource implements IDisposable, allowing it to free resources deterministically.

25. What are extension methods in C#?

Extension Methods: Allow adding new methods to existing types without modifying their source code. They are defined as static methods in a static class and use the this keyword in the first parameter to specify the type they extend.

Use Case: Useful for extending the functionality of existing types, especially when you do not have control over the source code of the type being extended.

public static class ParkExtensions
{
    public static void DisplayWelcomeMessage(this Park park)
    {
        Console.WriteLine($"Welcome to {park.Name}!");
    }
}

public class Park
{
    public string Name { get; set; }
}

public class Program
{
    public static void Main()
    {
        Park park = new Park { Name = "Olympic National Park" };
        park.DisplayWelcomeMessage();
    }
}

In this example, the DisplayWelcomeMessage method is added to the Park class as an extension method, allowing it to be called as if it were a member of the Park class.

These elaborated answers cover fundamental and advanced aspects of C#, providing a thorough understanding of each concept along with practical examples and use cases.

Scroll to Top