Interview

15 C#.NET Interview Questions and Answers

Prepare for your C#.NET interview with this guide, featuring curated questions and answers to enhance your understanding and confidence.

C#.NET is a versatile and powerful programming language developed by Microsoft, widely used for building a variety of applications, including web, desktop, and mobile solutions. Its strong typing, object-oriented features, and seamless integration with the .NET framework make it a preferred choice for developers working on enterprise-level projects. The language’s robust ecosystem and extensive libraries enable efficient development and maintenance of scalable applications.

This article aims to prepare you for your upcoming C#.NET interview by providing a curated selection of questions and answers. By familiarizing yourself with these topics, you will gain a deeper understanding of C#.NET’s core concepts and practical applications, enhancing your confidence and readiness for technical discussions.

C#.NET Interview Questions and Answers

1. How does garbage collection work in .NET?

Garbage collection in .NET is managed by the Common Language Runtime (CLR), which automatically handles memory allocation and release for applications. The garbage collector (GC) operates on the principle of generational collection, dividing objects into three generations: Generation 0 for short-lived objects, Generation 1 for objects that have survived one GC cycle, and Generation 2 for long-lived objects. The GC process involves marking objects in use, updating references, and compacting memory to reduce fragmentation. While the GC runs automatically, developers can manually trigger it using GC.Collect(), though this is generally discouraged due to potential performance issues.

2. Explain the concept of async and await.

In C#.NET, async and await keywords facilitate writing asynchronous code. The async keyword declares a method as asynchronous, while await pauses execution until the awaited task completes, allowing the program to remain responsive. For example:

public async Task<string> FetchDataAsync(string url)
{
    using (HttpClient client = new HttpClient())
    {
        HttpResponseMessage response = await client.GetAsync(url);
        response.EnsureSuccessStatusCode();
        string responseData = await response.Content.ReadAsStringAsync();
        return responseData;
    }
}

public async Task MainMethod()
{
    string data = await FetchDataAsync("https://example.com");
    Console.WriteLine(data);
}

Here, FetchDataAsync uses await to handle an HTTP GET request asynchronously, and MainMethod waits for its completion.

3. What are delegates and how are they used?

Delegates in C#.NET are type-safe pointers to methods, used for passing methods as arguments, defining callbacks, and implementing event handling. A delegate references a method matching its signature. For example:

using System;

public delegate void DisplayMessage(string message);

public class Program
{
    public static void Main()
    {
        DisplayMessage messageDelegate = ShowMessage;
        messageDelegate("Hello, World!");
    }

    public static void ShowMessage(string message)
    {
        Console.WriteLine(message);
    }
}

Here, DisplayMessage references methods with a single string parameter and void return type, like ShowMessage.

4. What is the difference between an abstract class and an interface?

Abstract classes and interfaces in C#.NET define methods for derived classes but differ in characteristics. Abstract classes can contain both abstract and concrete methods, fields, constructors, and support access modifiers. Interfaces only contain method signatures, properties, events, and indexers without implementation, and all members are implicitly public. For example:

// Abstract Class
public abstract class Animal
{
    public abstract void MakeSound();
    public void Sleep()
    {
        Console.WriteLine("Sleeping...");
    }
}

// Interface
public interface IAnimal
{
    void MakeSound();
}

public class Dog : Animal, IAnimal
{
    public override void MakeSound()
    {
        Console.WriteLine("Bark");
    }
}

5. What is dependency injection and why is it useful?

Dependency injection (DI) in C#.NET allows an object to receive its dependencies, typically through constructors, properties, or methods. DI decouples class creation from its dependencies, enhancing modularity and testability. For example:

public interface IService
{
    void Serve();
}

public class Service : IService
{
    public void Serve()
    {
        Console.WriteLine("Service Called");
    }
}

public class Client
{
    private readonly IService _service;

    public Client(IService service)
    {
        _service = service;
    }

    public void Start()
    {
        _service.Serve();
    }
}

// In a DI container setup
var service = new Service();
var client = new Client(service);
client.Start();

Here, Client depends on IService, receiving it through its constructor.

6. How do you create and use custom attributes?

Custom attributes in C#.NET add metadata to code elements, accessible at runtime using reflection. They are created by defining a class inheriting from System.Attribute. For example:

using System;

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class MyCustomAttribute : Attribute
{
    public string Description { get; }

    public MyCustomAttribute(string description)
    {
        Description = description;
    }
}

[MyCustomAttribute("This is a sample class with a custom attribute.")]
public class SampleClass
{
    [MyCustomAttribute("This is a sample method with a custom attribute.")]
    public void SampleMethod()
    {
        Console.WriteLine("SampleMethod executed.");
    }
}

class Program
{
    static void Main()
    {
        var type = typeof(SampleClass);
        var classAttributes = type.GetCustomAttributes(typeof(MyCustomAttribute), false);
        foreach (MyCustomAttribute attr in classAttributes)
        {
            Console.WriteLine($"Class Attribute Description: {attr.Description}");
        }

        var method = type.GetMethod("SampleMethod");
        var methodAttributes = method.GetCustomAttributes(typeof(MyCustomAttribute), false);
        foreach (MyCustomAttribute attr in methodAttributes)
        {
            Console.WriteLine($"Method Attribute Description: {attr.Description}");
        }
    }
}

Here, MyCustomAttribute is applied to SampleClass and SampleMethod, with descriptions retrieved using reflection.

7. What is the role of the Common Language Runtime (CLR)?

The Common Language Runtime (CLR) is the execution engine for .NET applications, providing services like memory management, security, exception handling, JIT compilation, type safety, and interoperability with unmanaged code.

8. How do you handle multi-threading in C#?

Multi-threading in C# allows concurrent execution of threads, improving resource use and performance. The .NET framework provides classes like Thread, ThreadPool, and Task Parallel Library (TPL) for handling multi-threading. Synchronization is essential to avoid race conditions, using constructs like lock, Monitor, Mutex, and Semaphore. For example:

using System;
using System.Threading;

class Program
{
    static void Main()
    {
        Thread thread = new Thread(new ThreadStart(DoWork));
        thread.Start();
        thread.Join();
    }

    static void DoWork()
    {
        Console.WriteLine("Work is being done on a separate thread.");
    }
}

And for synchronization:

class Program
{
    private static readonly object _lock = new object();

    static void Main()
    {
        Thread thread1 = new Thread(new ThreadStart(DoWork));
        Thread thread2 = new Thread(new ThreadStart(DoWork));
        thread1.Start();
        thread2.Start();
        thread1.Join();
        thread2.Join();
    }

    static void DoWork()
    {
        lock (_lock)
        {
            Console.WriteLine("Thread-safe work is being done.");
        }
    }
}

9. What are generics and how do they improve code reusability?

Generics in C#.NET allow defining classes, methods, delegates, and interfaces with a placeholder for data types, enhancing code reusability and type safety. For example:

List<int> intList = new List<int>();
intList.Add(1);
intList.Add(2);

List<string> stringList = new List<string>();
stringList.Add("Hello");
stringList.Add("World");

Here, List<T> is a generic class that can store any data type, avoiding the need for separate classes for each type.

10. Explain the concept of reflection and its uses.

Reflection in C#.NET enables runtime examination and manipulation of object types using the System.Reflection namespace. For example:

using System;
using System.Reflection;

public class Example
{
    public void PrintMessage()
    {
        Console.WriteLine("Hello, Reflection!");
    }
}

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

Here, reflection retrieves the PrintMessage method and invokes it on an Example instance.

11. How do you implement a singleton pattern in C#?

The singleton pattern in C# restricts a class to a single instance, providing a global access point. For example:

public class Singleton
{
    private static Singleton instance = null;
    private static readonly object padlock = new object();

    Singleton()
    {
    }

    public static Singleton Instance
    {
        get
        {
            lock (padlock)
            {
                if (instance == null)
                {
                    instance = new Singleton();
                }
                return instance;
            }
        }
    }
}

Here, the constructor is private, and a static variable holds the single instance, with a lock ensuring thread safety.

12. How do you manage state in a web application using ASP.NET Core?

In ASP.NET Core, state management in web applications can be achieved through session state, cookies, distributed cache, and TempData. For example, configuring session state in Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDistributedMemoryCache();
    services.AddSession(options =>
    {
        options.IdleTimeout = TimeSpan.FromMinutes(30);
        options.Cookie.HttpOnly = true;
        options.Cookie.IsEssential = true;
    });
    services.AddControllersWithViews();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseRouting();
    app.UseAuthorization();
    app.UseSession();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

13. Describe the role and implementation of middleware in ASP.NET Core.

Middleware in ASP.NET Core builds a request pipeline where each component can handle an HTTP request or response. To implement middleware, define a class with an Invoke or InvokeAsync method and add it to the pipeline in the Startup class. For example:

public class CustomMiddleware
{
    private readonly RequestDelegate _next;

    public CustomMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        await context.Response.WriteAsync("Before Middleware\n");
        await _next(context);
        await context.Response.WriteAsync("After Middleware\n");
    }
}

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.UseMiddleware<CustomMiddleware>();

        app.Run(async (context) =>
        {
            await context.Response.WriteAsync("Hello from the terminal middleware.\n");
        });
    }
}

Here, CustomMiddleware writes text to the response before and after calling the next middleware.

14. How do you write and run unit tests in C#?

Unit testing in C# involves testing individual units of code using frameworks like NUnit or MSTest. To write and run unit tests, create a test project, add a reference to the project to be tested, write test methods, and run them using a test runner. For example, using NUnit:

using NUnit.Framework;

namespace MyProject.Tests
{
    [TestFixture]
    public class CalculatorTests
    {
        [Test]
        public void Add_WhenCalled_ReturnsSum()
        {
            var calculator = new Calculator();
            var result = calculator.Add(1, 2);
            Assert.AreEqual(3, result);
        }
    }
}

Here, CalculatorTests contains a test method Add_WhenCalled_ReturnsSum that tests the Add method of the Calculator class.

15. Explain how to build and consume RESTful services in .NET.

To build a RESTful service in .NET, use ASP.NET Core. Create a new Web API project, define models and controllers, implement CRUD operations, and configure routing and middleware. For example, a simple controller:

[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    private readonly List<Product> _products = new List<Product>
    {
        new Product { Id = 1, Name = "Product1", Price = 10 },
        new Product { Id = 2, Name = "Product2", Price = 20 }
    };

    [HttpGet]
    public ActionResult<IEnumerable<Product>> GetProducts()
    {
        return _products;
    }

    [HttpGet("{id}")]
    public ActionResult<Product> GetProduct(int id)
    {
        var product = _products.FirstOrDefault(p => p.Id == id);
        if (product == null)
        {
            return NotFound();
        }
        return product;
    }

    [HttpPost]
    public ActionResult<Product> CreateProduct(Product product)
    {
        _products.Add(product);
        return CreatedAtAction(nameof(GetProduct), new { id = product.Id }, product);
    }
}

To consume a RESTful service, use the HttpClient class. For example:

public async Task<Product> GetProductAsync(int id)
{
    using (var client = new HttpClient())
    {
        client.BaseAddress = new Uri("https://example.com/api/");
        var response = await client.GetAsync($"products/{id}");
        response.EnsureSuccessStatusCode();

        var product = await response.Content.ReadAsAsync<Product>();
        return product;
    }
}
Previous

10 CRM Testing Interview Questions and Answers

Back to Interview
Next

15 PowerShell Scripting Interview Questions and Answers