Interview

10 C# Generics Interview Questions and Answers

Prepare for your C# interview with this guide on Generics. Enhance your understanding and showcase your expertise with curated questions and answers.

C# Generics provide a powerful way to define classes, methods, and data structures with a placeholder for the type of data they store or use. This feature enhances code reusability, type safety, and performance by allowing developers to create more flexible and maintainable code. Generics are a fundamental aspect of C# that can significantly optimize the development process, making them a crucial topic for any C# developer to master.

This article offers a curated selection of interview questions focused on C# Generics, designed to help you deepen your understanding and demonstrate your expertise. By familiarizing yourself with these questions and their answers, you will be better prepared to tackle technical interviews and showcase your proficiency in this essential area of C#.

C# Generics Interview Questions and Answers

1. Define a generic class that can store any type of data and demonstrate how to instantiate it with different types.

Generics in C# enable defining classes, methods, and data structures that can operate with any data type while maintaining type safety. This promotes code reusability and reduces the need for type casting.

Here is an example of a generic class in C#:

public class GenericStorage<T>
{
    private T data;

    public void SetData(T value)
    {
        data = value;
    }

    public T GetData()
    {
        return data;
    }
}

To instantiate this generic class with different types, you can do the following:

// Instantiate with an integer
GenericStorage<int> intStorage = new GenericStorage<int>();
intStorage.SetData(42);
int intData = intStorage.GetData();

// Instantiate with a string
GenericStorage<string> stringStorage = new GenericStorage<string>();
stringStorage.SetData("Hello, World!");
string stringData = stringStorage.GetData();

2. Write a generic method that takes two parameters of the same type and returns the one that is greater.

A generic method can compare two parameters of the same type and return the greater one. Here’s an example:

public static T Max<T>(T a, T b) where T : IComparable<T>
{
    return a.CompareTo(b) > 0 ? a : b;
}

The Max method uses a generic type T with a constraint ensuring T implements IComparable<T>, allowing the use of CompareTo.

3. Create a generic interface and demonstrate how to implement it in a class.

Here is an example of creating a generic interface and implementing it in a class:

// Define a generic interface
public interface IRepository<T>
{
    void Add(T item);
    T Get(int id);
}

// Implement the generic interface in a class
public class Repository<T> : IRepository<T>
{
    private List<T> _items = new List<T>();

    public void Add(T item)
    {
        _items.Add(item);
    }

    public T Get(int id)
    {
        return _items[id];
    }
}

// Usage
public class Program
{
    public static void Main()
    {
        IRepository<string> stringRepository = new Repository<string>();
        stringRepository.Add("Hello");
        Console.WriteLine(stringRepository.Get(0)); // Output: Hello

        IRepository<int> intRepository = new Repository<int>();
        intRepository.Add(42);
        Console.WriteLine(intRepository.Get(0)); // Output: 42
    }
}

4. Implement a generic class with multiple constraints on its type parameter.

Here is an example of a generic class with multiple constraints:

public interface IExampleInterface
{
    void ExampleMethod();
}

public class BaseClass
{
    public void BaseMethod() { }
}

public class GenericClass<T> where T : BaseClass, IExampleInterface, new()
{
    public T Instance { get; set; }

    public GenericClass()
    {
        Instance = new T();
    }

    public void Execute()
    {
        Instance.BaseMethod();
        Instance.ExampleMethod();
    }
}

In this example, GenericClass has a type parameter T with constraints: it must inherit from BaseClass, implement IExampleInterface, and have a parameterless constructor.

5. Write a nested generic class and demonstrate how to instantiate it.

Nested generic classes are useful for creating complex data structures or organizing code modularly. Here’s an example:

public class OuterClass<T>
{
    public class InnerClass<U>
    {
        public T OuterValue { get; set; }
        public U InnerValue { get; set; }

        public InnerClass(T outerValue, U innerValue)
        {
            OuterValue = outerValue;
            InnerValue = innerValue;
        }
    }
}

// Instantiating the nested generic class
OuterClass<int>.InnerClass<string> instance = new OuterClass<int>.InnerClass<string>(42, "Hello");

In this example, OuterClass<T> contains a nested generic class InnerClass<U>, demonstrating instantiation with specified types.

6. Implement a generic delegate and demonstrate its usage.

A generic delegate can operate with any data type. Here’s an example:

// Define a generic delegate
public delegate T Operation<T>(T a, T b);

class Program
{
    // Method that matches the delegate signature
    public static int Add(int a, int b)
    {
        return a + b;
    }

    public static void Main()
    {
        // Instantiate the generic delegate with int type
        Operation<int> addOperation = Add;
        
        // Use the delegate
        int result = addOperation(5, 3);
        Console.WriteLine(result); // Output: 8
    }
}

In this example, Operation<T> is a generic delegate used with different data types, demonstrated by the Add method.

7. Write a generic extension method for a collection and demonstrate its usage.

Here is an example of a generic extension method for a collection:

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

public static class CollectionExtensions
{
    public static IEnumerable<T> Filter<T>(this IEnumerable<T> source, Func<T, bool> predicate)
    {
        foreach (var item in source)
        {
            if (predicate(item))
            {
                yield return item;
            }
        }
    }
}

// Usage
class Program
{
    static void Main()
    {
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6 };
        var evenNumbers = numbers.Filter(n => n % 2 == 0);

        foreach (var number in evenNumbers)
        {
            Console.WriteLine(number);
        }
    }
}

8. Provide an example of using generic constraints with interfaces.

Generic constraints allow specifying requirements for a type argument. Here’s an example using interfaces:

public interface IPrintable
{
    void Print();
}

public class Document : IPrintable
{
    public void Print()
    {
        Console.WriteLine("Printing Document");
    }
}

public class Report : IPrintable
{
    public void Print()
    {
        Console.WriteLine("Printing Report");
    }
}

public class Printer<T> where T : IPrintable
{
    public void PrintDocument(T document)
    {
        document.Print();
    }
}

class Program
{
    static void Main()
    {
        Printer<Document> documentPrinter = new Printer<Document>();
        documentPrinter.PrintDocument(new Document());

        Printer<Report> reportPrinter = new Printer<Report>();
        reportPrinter.PrintDocument(new Report());
    }
}

In this example, Printer<T> uses a constraint to ensure T implements IPrintable, allowing PrintDocument to call Print.

9. Discuss how LINQ leverages generic collections.

LINQ leverages generic collections to provide querying capabilities for various data sources. By using generics, LINQ can work with any collection implementing IEnumerable<T>, allowing for type-safe queries.

Here’s an example demonstrating LINQ with a generic List<T>:

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

class Program
{
    static void Main()
    {
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

        var evenNumbers = numbers.Where(n => n % 2 == 0).ToList();

        foreach (var num in evenNumbers)
        {
            Console.WriteLine(num);
        }
    }
}

In this example, the Where method filters elements of the generic List<int> based on a condition, resulting in a list of even numbers.

10. Describe a real-world scenario where generics significantly improve code quality or performance.

Generics can significantly improve code quality by reducing redundancy and increasing reusability. They also enhance performance by eliminating the need for type casting and boxing/unboxing operations.

A real-world scenario where generics improve code quality and performance is in implementing a type-safe collection, such as a list. Without generics, you would have to use a non-generic collection like ArrayList, which stores elements as objects, requiring type casting and potentially leading to runtime errors.

Example:

using System;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        List<int> numbers = new List<int>();
        numbers.Add(1);
        numbers.Add(2);
        numbers.Add(3);

        foreach (int number in numbers)
        {
            Console.WriteLine(number);
        }
    }
}

In this example, List<int> is a generic collection that ensures type safety, allowing only integers and eliminating the need for type casting.

Previous

10 Apache Hive Interview Questions and Answers

Back to Interview
Next

15 Op Amp Interview Questions and Answers