NET Core Interview Questions for 2025

author image Hirely
at 09 Jan, 2025

Question: What are delegates and events in .NET?

Answer:

In .NET, delegates and events are key concepts for managing methods and event-driven programming. They work together to allow methods to be passed as parameters and to notify objects when something happens. Below is an explanation of both concepts:


1. Delegates in .NET

Definition:

A delegate is a type that represents a reference to a method. It is similar to a pointer to a function in C or C++, but it is type-safe and object-oriented in C#. Delegates allow methods to be passed as parameters, stored as variables, and invoked dynamically.

Characteristics:

  • Type-safe: The signature of the delegate must match the signature of the method it points to.
  • Encapsulates a method: A delegate can reference both instance methods and static methods.
  • Multicast: A delegate can point to multiple methods and invoke them sequentially.

Syntax:

// Delegate declaration
public delegate void MyDelegate(string message);

// Method matching the delegate signature
public void PrintMessage(string message)
{
    Console.WriteLine(message);
}

// Usage
MyDelegate del = new MyDelegate(PrintMessage);
del("Hello, World!");  // Output: Hello, World!

Types of Delegates:

  1. Single-cast delegates: A delegate that points to a single method.
  2. Multicast delegates: A delegate that can point to multiple methods. The methods are invoked in the order they were added.
    public delegate void MyDelegate(string message);
    
    MyDelegate del1 = PrintMessage1;
    MyDelegate del2 = PrintMessage2;
    
    MyDelegate combinedDelegate = del1 + del2;
    combinedDelegate("Hello, Multicast!"); // Calls both PrintMessage1 and PrintMessage2

Common Delegate Types:

  • Action: A delegate that returns void and can take parameters.
  • Func: A delegate that returns a value and can take parameters.
  • Predicate: A special kind of delegate used for methods that return a boolean value.

Example with Action:

Action<string> greet = name => Console.WriteLine($"Hello, {name}!");
greet("Alice");  // Output: Hello, Alice!

2. Events in .NET

Definition:

An event is a mechanism that provides notifications. It is based on delegates and is used for event-driven programming, where one object (the publisher) notifies other objects (the subscribers) about changes or actions.

Events are usually used for implementing the observer pattern, where one or more objects (subscribers) “listen” for events that are triggered by another object (publisher).

Characteristics:

  • Encapsulation: Events allow methods (subscribers) to be attached to them, but the publisher cannot directly invoke the event’s delegate. The delegate is invoked only by the event itself.
  • Add/Remove Accessors: Events are typically accessed through add and remove accessors (provided automatically by the compiler), ensuring the event can only be triggered by the class that declares it.

Syntax:

// Delegate declaration for the event
public delegate void Notify();  // No parameters, void return type

// Publisher class
public class Publisher
{
    public event Notify OnNotify;  // Event declaration

    public void TriggerEvent()
    {
        if (OnNotify != null)  // Check if there are subscribers
        {
            OnNotify();  // Invoke the event
        }
    }
}

// Subscriber class
public class Subscriber
{
    public void RespondToEvent()
    {
        Console.WriteLine("Event triggered!");
    }
}

// Usage
Publisher publisher = new Publisher();
Subscriber subscriber = new Subscriber();

// Subscribing to the event
publisher.OnNotify += subscriber.RespondToEvent;

// Trigger the event
publisher.TriggerEvent();  // Output: Event triggered!

Key Points About Events:

  1. Event Subscription: To “subscribe” to an event, a method must match the delegate signature of the event.
  2. Event Publishing: The event can only be raised by the object that declares it, ensuring the publisher controls the invocation of the event.
  3. Unsubscription: You can “unsubscribe” from an event, removing the method from the delegate chain.
  4. Multicast Events: Just like multicast delegates, events can have multiple subscribers, and all of them are invoked when the event is raised.

Common Event Patterns:

  • Event Handler Pattern: Used to handle events with additional information, such as UI events.

    Example with EventHandler:

    public class MyEventPublisher
    {
        // Define the event using EventHandler
        public event EventHandler<MyEventArgs> MyEvent;
    
        public void RaiseEvent()
        {
            MyEvent?.Invoke(this, new MyEventArgs("Hello from event"));
        }
    }
    
    public class MyEventArgs : EventArgs
    {
        public string Message { get; }
        public MyEventArgs(string message) { Message = message; }
    }
    
    public class MyEventSubscriber
    {
        public void MyEventHandler(object sender, MyEventArgs e)
        {
            Console.WriteLine(e.Message);  // Output: Hello from event
        }
    }
    
    // Usage
    MyEventPublisher publisher = new MyEventPublisher();
    MyEventSubscriber subscriber = new MyEventSubscriber();
    
    // Subscribe to the event
    publisher.MyEvent += subscriber.MyEventHandler;
    
    // Raise the event
    publisher.RaiseEvent();

Key Differences Between Delegates and Events

FeatureDelegateEvent
DefinitionA type that represents references to methods.A notification mechanism that uses delegates.
UsageUsed to define method references, callback functions.Used to notify subscribers when something happens.
Direct InvocationCan be invoked directly by the code that holds the delegate.Can only be invoked by the class that defines the event.
Multiple SubscribersSupports multicast delegates (multiple methods).Can have multiple subscribers, but cannot be directly invoked.
Access ModifiersCan have public, private, protected access modifiers.Event access modifiers are typically add and remove methods.
FunctionalityDelegates can be passed around like objects.Events provide a controlled mechanism to attach methods (event handlers).
PurposeDelegate can be used for any method invocation.Events are specifically for the publisher-subscriber model (notifications).

Summary:

  • Delegates: A delegate is a type that defines a method signature and can reference methods with that signature. It allows methods to be passed as parameters, stored as variables, and invoked dynamically. Delegates can be used for callbacks and custom event handling.

  • Events: An event is a mechanism to notify subscribers about changes or actions. Events are based on delegates but provide a controlled way for methods to subscribe and unsubscribe. Events allow a publisher to notify multiple subscribers without directly invoking their methods.

Together, delegates and events are foundational for creating flexible and decoupled systems, particularly in scenarios involving event-driven programming.

Question: What are the differences between a value type and a reference type in .NET?

Answer:

In .NET, value types and reference types are two fundamental categories of types, and they differ significantly in how they are stored and managed in memory. Below are the key differences between them:


1. Memory Allocation:

  • Value Types:

    • Value types are stored directly in the stack.
    • When a value type variable is assigned to another, a copy of the value is made.
    • The memory for value types is automatically freed when they go out of scope.
  • Reference Types:

    • Reference types are stored on the heap, while the reference (pointer) to the object is stored in the stack.
    • When a reference type variable is assigned to another, only the reference (address) is copied, not the actual data. Both variables point to the same object in memory.
    • The memory for reference types is managed by the garbage collector.

2. Types:

  • Value Types:
    • Includes basic data types like int, float, char, bool, structs, and enums.
    • All primitive types in .NET are value types.
    • Structs and enums are also value types.
  • Reference Types:
    • Includes classes, arrays, delegates, and strings.
    • Custom objects (defined using class) are reference types.

3. Assignment Behavior:

  • Value Types:

    • When you assign a value type to another variable, a copy of the value is made.
    • Modifying the copied value does not affect the original value.
    int a = 10;
    int b = a; // b is a copy of a
    b = 20;    // a is still 10, b is now 20
  • Reference Types:

    • When you assign a reference type to another variable, both variables point to the same object in memory.
    • Modifying the object through one reference affects the object seen by the other reference.
    class Person
    {
        public string Name { get; set; }
    }
    Person p1 = new Person { Name = "Alice" };
    Person p2 = p1; // p2 points to the same object as p1
    p2.Name = "Bob"; // p1.Name is also "Bob" since both p1 and p2 refer to the same object

4. Default Values:

  • Value Types:
    • Each value type has a default value when not initialized. For example:
      • int defaults to 0.
      • bool defaults to false.
      • float defaults to 0.0.
  • Reference Types:
    • Reference types default to null when not initialized, meaning they do not point to any object.

5. Nullability:

  • Value Types:

    • Value types cannot be assigned null (except for nullable value types, which are indicated by ?).
    int x = 10;
    // x = null; // Error: Cannot assign null to a non-nullable value type.
    
    int? y = null; // Nullable value type
  • Reference Types:

    • Reference types can always be assigned null, indicating that they do not refer to any object.
    string name = null; // Valid
    Person person = null; // Valid

6. Performance Considerations:

  • Value Types:
    • Value types are typically faster when used for small data sizes because they are stored on the stack, and there is no need for heap allocation or garbage collection.
    • However, copying large structs frequently can lead to performance issues.
  • Reference Types:
    • Reference types involve heap allocation and may require more memory overhead because the object is stored on the heap.
    • They also rely on garbage collection, which can cause performance hiccups during collection cycles.

7. Inheritance:

  • Value Types:
    • Value types cannot inherit from other value types or reference types (except for System.Object, which all types inherit).
    • Value types are sealed by default (i.e., you cannot subclass them).
  • Reference Types:
    • Reference types can inherit from other reference types and can form class hierarchies.
    • Classes can inherit from other classes, and interfaces can be implemented by classes.

8. Examples:

  • Value Types:

    int x = 42;
    double y = 3.14;
    bool isActive = true;
    
    struct Point
    {
        public int X;
        public int Y;
    }
    Point p1 = new Point { X = 10, Y = 20 };
  • Reference Types:

    string str = "Hello, World!";
    Person person = new Person { Name = "Alice", Age = 30 };
    
    class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }

Summary of Key Differences:

FeatureValue TypesReference Types
Memory AllocationStored on the stackStored on the heap, reference in the stack
AssignmentCopy of the value is made (independent)Reference (address) of the object is copied (shared)
NullabilityCannot be null (unless nullable)Can be null
InheritanceCannot inherit from other types (sealed by default)Can inherit from other classes (supports polymorphism)
Default ValueDefault to a specific value (e.g., 0, false)Default to null
PerformanceFaster for small data sizes, no GC overheadPotentially slower due to heap allocation and GC
Examplesint, float, struct, enumclass, string, array, delegate

Conclusion:

  • Value types are typically used for small, simple data structures where performance is critical, and where the value itself is important (such as primitive types and structs).
  • Reference types are used for more complex data structures that may need to support inheritance, reference sharing, or dynamic behavior (such as classes, arrays, and strings).

Understanding the differences between value types and reference types is essential for effective memory management and performance optimization in .NET applications.

Read More

If you can’t get enough from this article, Aihirely has plenty more related information, such as .NET interview questions, .NET interview experiences, and details about various .NET job positions. Click here to check it out.

Related Posts

Trace Job opportunities

Hirely, your exclusive interview companion, empowers your competence and facilitates your interviews.

Get Started Now