C%23 Interview Questions and Answers 2024
Try Aihirely for
Smarter Interview Prep
 Experience real-time AI support tailored to your Resume.
Boost your confidence and ace every question with
AI Mock Interview.
Question: What is the difference between a class and a struct in C#?
Answer:
In C#, both class and struct are user-defined data types that are used to represent objects, but there are key differences between them in terms of memory allocation, behavior, and usage. Let’s go over the main differences:
1. Memory Allocation:
- 
Class:
- A 
classis a reference type, which means it is allocated on the heap. - When you create an object of a class, the object itself is stored on the heap, and the reference to the object is stored on the stack.
 - This results in objects of classes being garbage collected when they are no longer in use (i.e., when the reference to the object goes out of scope).
 
 - A 
 - 
Struct:
- A 
structis a value type, which means it is allocated on the stack (unless it’s boxed). - When you create a struct, its actual data is stored directly where it was defined (e.g., in a method’s local variables or in an array).
 - Structs are not garbage collected, and they are cleaned up automatically when they go out of scope.
 
 - A 
 
2. Default Constructor:
- 
Class:
- A class can have a default constructor (i.e., a constructor with no parameters), but if it does not explicitly define one, the compiler provides a default parameterless constructor.
 
 - 
Struct:
- A struct cannot have an explicit default constructor. It always gets a default constructor (provided by the compiler) that initializes all its fields to their default values (e.g., 
0forint,falseforbool, etc.). - However, you can define constructors that take parameters.
 
 - A struct cannot have an explicit default constructor. It always gets a default constructor (provided by the compiler) that initializes all its fields to their default values (e.g., 
 
3. Inheritance:
- 
Class:
- A class can inherit from another class and can be inherited from (i.e., it supports inheritance).
 - Classes also support polymorphism, meaning derived classes can override methods of base classes.
 
 - 
Struct:
- A struct cannot inherit from another struct or class, nor can it be inherited from. Structs do not support inheritance (except for implicitly inheriting from 
System.ValueType). - You can implement interfaces in structs, but they cannot inherit from other types.
 
 - A struct cannot inherit from another struct or class, nor can it be inherited from. Structs do not support inheritance (except for implicitly inheriting from 
 
4. Nullability:
- 
Class:
- Since a class is a reference type, it can be assigned 
nullby default. A class object can be null, which represents the absence of an instance. 
 - Since a class is a reference type, it can be assigned 
 - 
Struct:
- A struct is a value type, so it cannot be 
nullby default. However, you can create a nullable struct using the?syntax (e.g.,int?), which allows the struct to represent a value ornull. 
 - A struct is a value type, so it cannot be 
 
5. Performance:
- 
Class:
- Classes tend to have higher memory overhead because they are reference types. They require heap allocation and garbage collection, which can have performance costs.
 - Passing a class object to a method involves passing the reference (a pointer), which is relatively fast.
 
 - 
Struct:
- Structs are more memory efficient for small, lightweight data types because they are value types and stored on the stack.
 - However, passing large structs by value (i.e., copying the entire struct) can be expensive in terms of performance. It’s better to pass structs by reference using 
reforoutwhen dealing with large structs. 
 
6. Equality:
- 
Class:
- When comparing two class objects using the 
==operator, it compares their references (i.e., whether they point to the same object in memory). - To compare their contents, you must override the 
Equals()method and the==operator. 
 - When comparing two class objects using the 
 - 
Struct:
- When comparing two structs, the 
==operator compares their values (i.e., the actual data stored in the struct), not their references. - Structs provide a default implementation of 
Equals()that compares the contents of the structs, but this can be overridden if needed. 
 - When comparing two structs, the 
 
7. Boxing and Unboxing:
- 
Class:
- Since classes are reference types, there is no need to box them. They are always stored as references.
 
 - 
Struct:
- When a struct is assigned to a variable of type 
object(or any interface type), it is boxed. Boxing involves copying the struct’s value to the heap and wrapping it in an object reference. - Unboxing is required to extract the value from a boxed struct, which can be more expensive than working directly with a value type.
 
 - When a struct is assigned to a variable of type 
 
8. Use Cases:
- 
Class:
- Use a 
classwhen you need to represent objects with complex behavior (such as inheritance, polymorphism, or when the object needs to be passed by reference). - Classes are suitable for large, mutable objects that require more memory and manage resources.
 
 - Use a 
 - 
Struct:
- Use a 
structfor small, lightweight, immutable data types that do not require inheritance or polymorphism. - Structs are ideal for representing simple value types like coordinates, ranges, or key-value pairs.
 
 - Use a 
 
9. Example:
Class Example:
class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    
    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
}
Person p1 = new Person("Alice", 30);
Person p2 = p1;
p2.Age = 35;
Console.WriteLine(p1.Age); // Output: 35 (p1 and p2 refer to the same object)
Struct Example:
struct Point
{
    public int X;
    public int Y;
    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }
}
Point p1 = new Point(10, 20);
Point p2 = p1; // p2 gets a copy of p1
p2.X = 30;
Console.WriteLine(p1.X); // Output: 10 (p1 and p2 are different copies)
Summary of Differences:
| Feature | Class | Struct | 
|---|---|---|
| Type | Reference Type | Value Type | 
| Memory Allocation | Heap | Stack | 
| Default Constructor | Can have a parameterless constructor | Cannot define a parameterless constructor | 
| Inheritance | Supports inheritance and polymorphism | Does not support inheritance or polymorphism | 
| Nullability | Can be null | Cannot be null unless nullable (?) | 
| Performance | Higher memory overhead, slower (GC) | More memory efficient, faster for small types | 
| Equality | Compares references by default | Compares values by default | 
| Boxing/Unboxing | No boxing/unboxing needed | Boxing is required when assigned to object | 
| Use Case | Suitable for complex, large, and mutable data | Suitable for small, immutable, and lightweight data | 
In general, you should use a class when you need reference semantics, inheritance, or polymorphism, and use a struct when you need a lightweight, immutable data type where performance is critical and inheritance is unnecessary.
Question: What is the purpose of the Finalize method in C#?
Answer:
In C#, the Finalize method is part of the destructor mechanism used by the garbage collector (GC) to clean up resources before an object is reclaimed from memory. This method allows an object to perform any final cleanup (such as releasing unmanaged resources like file handles, database connections, or network connections) before the object is destroyed.
Key Points:
- 
Automatic Cleanup:
- The 
Finalizemethod is called by the garbage collector just before an object is removed from memory. - It provides a way to release resources that are not managed by the garbage collector (i.e., unmanaged resources such as memory allocated through unmanaged code, file streams, or database connections).
 
 - The 
 - 
Naming:
- The 
Finalizemethod in C# is typically defined using the destructor syntax, which has the same name as the class, preceded by a tilde (~). - Syntax:
~ClassName() { // Finalization code here } 
 - The 
 - 
Managed vs. Unmanaged Resources:
- The garbage collector in C# automatically manages memory for managed resources (like objects and arrays). However, it does not handle unmanaged resources, which is where 
Finalizecomes into play. - For managed resources (e.g., memory), the garbage collector will automatically clean them up, but unmanaged resources must be explicitly released, and that’s what 
Finalizeis intended for. 
 - The garbage collector in C# automatically manages memory for managed resources (like objects and arrays). However, it does not handle unmanaged resources, which is where 
 - 
Important Notes:
- Non-deterministic: You cannot directly control when 
Finalizeis called because the garbage collector schedules the finalization at an unspecified time. This is why it is considered non-deterministic. - Performance Impact: The use of 
Finalizecan slow down the garbage collection process because objects that implementFinalizeare placed on a finalization queue and must go through an extra step of finalization before they are actually removed from memory. - Use with Caution: Because of the non-deterministic nature of 
Finalize, it is generally not recommended to rely on it for critical resource management. Instead, theDisposepattern (viaIDisposableinterface) is used to allow developers to release unmanaged resources deterministically. 
 - Non-deterministic: You cannot directly control when 
 - 
Dispose Pattern:
- To ensure proper and timely cleanup of unmanaged resources, it is common practice to implement both a 
Disposemethod (fromIDisposable) and aFinalizemethod. This allows developers to manage the release of resources manually when they are done using them and to provide a safety net in case theDisposemethod is not called. - The 
Disposemethod is usually called explicitly, whileFinalizeacts as a backup mechanism ifDisposeis not called. 
 - To ensure proper and timely cleanup of unmanaged resources, it is common practice to implement both a 
 
Example of Finalize Method in C#:
class MyClass
{
    // Unmanaged resource (e.g., file handle, database connection)
    private IntPtr unmanagedResource;
    // Constructor
    public MyClass()
    {
        // Allocate unmanaged resource
        unmanagedResource = /* allocate unmanaged resource */;
    }
    // Finalizer (destructor)
    ~MyClass()
    {
        // Cleanup unmanaged resource
        if (unmanagedResource != IntPtr.Zero)
        {
            // Release unmanaged resource (e.g., close a file or release a handle)
            unmanagedResource = IntPtr.Zero;
        }
        Console.WriteLine("Finalize method called");
    }
    // Dispose method for manual cleanup (better practice)
    public void Dispose()
    {
        // Release unmanaged resource manually
        if (unmanagedResource != IntPtr.Zero)
        {
            unmanagedResource = IntPtr.Zero;
        }
        GC.SuppressFinalize(this);  // Suppress finalizer to prevent it from running
        Console.WriteLine("Dispose method called");
    }
}
class Program
{
    static void Main()
    {
        // Example of using the class
        MyClass obj = new MyClass();
        obj.Dispose();  // Manually dispose of the object
    }
}
In this example:
- The 
Finalizemethod releases unmanaged resources when the object is about to be collected by the garbage collector. - The 
Disposemethod provides a more deterministic way to clean up unmanaged resources when you’re done using the object, and the call toGC.SuppressFinalize(this)tells the garbage collector that finalization is not needed, which can improve performance. 
Key Takeaways:
- Purpose: The 
Finalizemethod provides a way to clean up unmanaged resources before an object is destroyed by the garbage collector. - Non-deterministic: You cannot predict when 
Finalizewill be called, so it is generally not used for critical resource management. - Dispose Pattern: For better resource management, you should use the 
Disposepattern (viaIDisposable), which allows you to release resources explicitly and deterministically. 
Read More
If you can’t get enough from this article, Aihirely has plenty more related information, such as C# interview questions, C# interview experiences, and details about various C# job positions. Click here to check it out.
