Skip to main content

C# : Interview questions (71-75)


Questions:

  • What is a generic method?
  • Explain the use of constraints in generics.
  • What is covariance and contravariance in generics?
  • What are anonymous types in C#?
  • How do you implement anonymous methods in C#?
Answers:

1. What is a Generic Method?

A generic method in C# is a method that is defined with a type parameter. This allows the method to operate on different data types without needing to be rewritten for each type. Generic methods provide type safety, reduce code duplication, and improve performance.

public class Utilities
{
    public void Swap<T>(ref T a, ref T b)
    {
        T temp = a;
        a = b;
        b = temp;
    }
}

// Usage
int x = 1, y = 2;
Utilities utilities = new Utilities();
utilities.Swap(ref x, ref y);
Console.WriteLine($"x: {x}, y: {y}"); // Output: x: 2, y: 1

In this example, the Swap method is a generic method that can swap the values of two variables of any type.

2. Use of Constraints in Generics:

Constraints in generics are used to restrict the types that can be used as arguments for a type parameter. This ensures that the type arguments meet certain requirements, providing more control over the behavior of generic classes and methods.

public class Utilities
{
    // Constraint to ensure T implements IComparable<T>
    public T Max<T>(T a, T b) where T : IComparable<T>
    {
        return a.CompareTo(b) > 0 ? a : b;
    }
}

// Usage
Utilities utilities = new Utilities();
int maxInt = utilities.Max(10, 20);
string maxString = utilities.Max("apple", "banana");
Console.WriteLine($"Max Int: {maxInt}, Max String: {maxString}"); // Output: Max Int: 20, Max String: banana

In this example, the Max method has a constraint that ensures the type parameter T implements IComparable<T>, allowing the method to compare values of type T.

3. Covariance and Contravariance in Generics:

  • Covariance: Allows a generic type to be assigned to another generic type with a more derived type parameter. It is applicable to reference types and is denoted using the out keyword.
IEnumerable<string> strings = new List<string>();
IEnumerable<object> objects = strings; // Covariance
  • Contravariance: Allows a generic type to be assigned to another generic type with a less derived type parameter. It is applicable to reference types and is denoted using the in keyword.
Action<object> actionObject = (object obj) => Console.WriteLine(obj);
Action<string> actionString = actionObject; // Contravariance

In these examples, covariance allows an IEnumerable<string> to be assigned to an IEnumerable<object>, and contravariance allows an Action<object> to be assigned to an Action<string>.

4. Anonymous Types in C#:

Anonymous types in C# provide a way to create a new type without explicitly defining it. They are primarily used for convenience in scenarios where defining a new type would be overkill, such as in LINQ queries.

var person = new { Name = "John", Age = 30 };
Console.WriteLine($"Name: {person.Name}, Age: {person.Age}"); // Output: Name: John, Age: 30

In this example, an anonymous type with properties Name and Age is created and assigned to the variable person.

5. Implementing Anonymous Methods in C#:

Anonymous methods in C# provide a way to define inline methods without having to explicitly declare them. They are primarily used in delegate assignments and event handling.

delegate void PrintDelegate(string message);

class Program
{
    static void Main()
    {
        PrintDelegate print = delegate (string message)
        {
            Console.WriteLine(message);
        };

        print("Hello, world!"); // Output: Hello, world!
    }
}

In this example, an anonymous method is assigned to the print delegate, which prints a message to the console.

Alternatively, you can use lambda expressions, which provide a more concise syntax for anonymous methods:

PrintDelegate print = (message) => Console.WriteLine(message);
print("Hello, world!"); // Output: Hello, world!
Both approaches achieve the same result but lambda expressions offer a cleaner and more readable syntax.

Comments

Popular posts from this blog

Clean Architecture: What It Is and How It Differs from Microservices

In the tech world, buzzwords like   Clean Architecture   and   Microservices   often dominate discussions about building scalable, maintainable applications. But what exactly is Clean Architecture? How does it compare to Microservices? And most importantly, is it more efficient? Let’s break it all down, from understanding the core principles of Clean Architecture to comparing it with Microservices. By the end of this blog, you’ll know when to use each and why Clean Architecture might just be the silent hero your projects need. What is Clean Architecture? Clean Architecture  is a design paradigm introduced by Robert C. Martin (Uncle Bob) in his book  Clean Architecture: A Craftsman’s Guide to Software Structure and Design . It’s an evolution of layered architecture, focusing on organizing code in a way that makes it  flexible ,  testable , and  easy to maintain . Core Principles of Clean Architecture Dependency Inversion : High-level modules s...

20+ LINQ Concepts with .Net Code

LINQ   (Language Integrated Query) is one of the most powerful features in .NET, providing a unified syntax to query collections, databases, XML, and other data sources. Below are 20+ important LINQ concepts, their explanations, and code snippets to help you understand their usage. 1.  Where  (Filtering) The  Where()  method is used to filter a collection based on a given condition. var numbers = new List < int > { 1 , 2 , 3 , 4 , 5 , 6 } ; var evenNumbers = numbers . Where ( n => n % 2 == 0 ) . ToList ( ) ; // Output: [2, 4, 6] C# Copy 2.  Select  (Projection) The  Select()  method projects each element of a sequence into a new form, allowing transformation of data. var employees = new List < Employee > { /* ... */ } ; var employeeNames = employees . Select ( e => e . Name ) . ToList ( ) ; // Output: List of employee names C# Copy 3.  OrderBy  (Sorting in Ascending Order) The  Or...

Implementing and Integrating RabbitMQ in .NET Core Application: Shopping Cart and Order API

RabbitMQ is a robust message broker that enables communication between services in a decoupled, reliable manner. In this guide, we’ll implement RabbitMQ in a .NET Core application to connect two microservices: Shopping Cart API (Producer) and Order API (Consumer). 1. Prerequisites Install RabbitMQ locally or on a server. Default Management UI: http://localhost:15672 Default Credentials: guest/guest Install the RabbitMQ.Client package for .NET: dotnet add package RabbitMQ.Client 2. Architecture Overview Shopping Cart API (Producer): Sends a message when a user places an order. RabbitMQ : Acts as the broker to hold the message. Order API (Consumer): Receives the message and processes the order. 3. RabbitMQ Producer: Shopping Cart API Step 1: Install RabbitMQ.Client Ensure the RabbitMQ client library is installed: dotnet add package RabbitMQ.Client Step 2: Create the Producer Service Add a RabbitMQProducer class to send messages. RabbitMQProducer.cs : using RabbitMQ.Client; usin...