0% found this document useful (0 votes)
32 views40 pages

C# Interview Questions

The document contains a comprehensive list of C# interview questions and answers, covering topics from basic syntax and data types to advanced concepts like dependency injection and design patterns. It categorizes questions into beginner, intermediate, and experienced levels, providing insights into key C# features such as value types, reference types, boxing, unboxing, extension methods, and more. Additionally, it includes specific comparisons between various C# constructs like classes, structs, and records.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
32 views40 pages

C# Interview Questions

The document contains a comprehensive list of C# interview questions and answers, covering topics from basic syntax and data types to advanced concepts like dependency injection and design patterns. It categorizes questions into beginner, intermediate, and experienced levels, providing insights into key C# features such as value types, reference types, boxing, unboxing, extension methods, and more. Additionally, it includes specific comparisons between various C# constructs like classes, structs, and records.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

C# Interview Questions

What is the main boxing unboxing Is string a value or


difference between reference type
value types and
reference types
Why is string Is string a value or Ref and out Extension method
immutable reference type
Why are extension Can extension Can extension Method hiding
methods needed methods be methods be
defined for sealed defined for value
classes types
Why is new Record vs Class All questions
keyword used vs Struct

What is the main difference between value types and reference types?

Answer:

Value Type Reference Type

Stores actual value Stores memory reference

Stored on stack Stored on heap

Copy creates new value Copy creates shared reference

Faster allocation Slower due to heap allocation

What is boxing in C#?

Answer:
Boxing converts a value type to an object/reference type.

int x = 10;
object obj = x; // Boxing

What is unboxing?

Answer:
Extracting the value type from an object.

int y = (int)obj; // Unboxing


Is string a value or reference type?

Answer:
string is a reference type, but it is immutable.

Why is string immutable?

Answer:
For:

• Thread safety
• Security
• String interning
• Performance optimizations

ref

• Used to pass a variable by reference


• The variable must be initialized before passing
• Method can read and modify the value

Example
void UpdateValue(ref int x)
{
x = x + 10;
}

int a = 5;
UpdateValue(ref a);
// a = 15

out
Key Differences (Quick)

Feature ref out

Initialization required before call ✅ Yes ❌ No

Must be assigned inside method ❌ No ✅ Yes

Used for Modify existing value Return value


When to use what?

• Use ref when you already have a value and want to update it
• Use out when you want a method to produce a value

What is an extension method?

Answer:
An extension method allows you to add new methods to an existing type without
modifying, inheriting, or recompiling it.

Why are extension methods needed?

Answer:

• To add functionality to sealed classes


• To extend .NET built-in types (e.g., string, DateTime)
• To improve readability and reusability
• Widely used in LINQ

Can extension methods be defined for sealed classes?

Answer:
✅ Yes.
This is one of their main use cases.

Can extension methods be defined for value types?

Answer:
✅ Yes, but the value type is passed by value, unless ref is used

What is method hiding?

Answer:
Method hiding occurs when a derived class defines a method with the same name as a base
class method using the new keyword.

Why is new keyword used?

Answer:
To explicitly indicate that the derived method hides the base class method.

Record vs Class vs Struct (C#)


Feature Class Struct Record
Type Reference Value Reference (default)
Mutability Mutable Mutable Immutable by default
Equality Reference-based Value-based Value-based
Inheritance Yes No Yes
Use Case Business logic Small data DTOs, models

Beginner (40 Questions)


1. What is C#?
2. Explain the basic syntax of C#.
3. What are data types in C#?
4. What is the difference between int and Int32?
5. How do you declare a variable in C#?
6. What are operators in C#?
7. Explain the difference between == and === in C#.
8. What is a namespace in C#?
9. How do you handle exceptions in C#?
10. What is a constructor?
11. What is an array in C#?
12. How do you create a list in C#?
13. What is the difference between List<T> and an array?
14. What are properties in C#?
15. Explain the concept of encapsulation.
16. What is an interface in C#?
17. What is the purpose of the using statement?
18. How do you read from and write to a file in C#?
19. What is the Main method?
20. How do you create a simple console application?
21. What are access modifiers in C#?
22. What is the difference between public, private, protected, and internal?
23. Explain the concept of inheritance.
24. What is polymorphism?
25. How do you implement method overloading in C#?
26. What is a static class?
27. How do you convert a string to an integer in C#?
28. What are collections in C#?
29. What is a delegate?
30. What is an event in C#?
31. How do you create a switch statement?
32. What are tuples in C#?
33. What is the difference between a value type and a reference type?
34. Explain the concept of a nullable type.
35. What is garbage collection?
36. How do you use a foreach loop?
37. What are lambda expressions?
38. How do you handle multiple exceptions in C#?
39. What is LINQ?
40. Explain the difference between string and StringBuilder.

Intermediate (40 Questions)


1. What are generics in C#?
2. Explain the async and await keywords.
3. What is dependency injection?
4. How do you implement interfaces in C#?
5. What is reflection?
6. Explain the concept of attributes in C#.
7. How does the IDisposable interface work?
8. What are extension methods?
9. How do you handle threading in C#?
10. What is the difference between Task and Thread?
11. Explain the lock statement.
12. What is the volatile keyword?
13. How do you work with JSON in C#?
14. What is a lambda expression and how is it used?
15. What are anonymous types?
16. How do you implement asynchronous programming in C#?
17. What is the purpose of the async keyword?
18. How can you prevent a class from being instantiated?
19. Explain the concept of a singleton pattern.
20. What is the difference between abstract classes and interfaces?
21. How do you implement the observer pattern in C#?
22. What are the main differences between IEnumerable and IQueryable?
23. How do you handle large data sets in C#?
24. What is a circular reference?
25. Explain the use of yield in C#.
26. What is the purpose of the params keyword?
27. How do you implement unit testing in C#?
28. What is a custom exception?
29. What is [Link]?
30. How do you use Entity Framework?
31. What is a partial class?
32. What is the difference between throw and throw ex?
33. How do you implement logging in C# applications?
34. What is a dynamic type in C#?
35. How do you serialize and deserialize an object?
36. What are the differences between const and readonly?
37. How do you create a custom collection?
38. Explain the differences between List<T> and Dictionary<TKey, TValue>.
39. What is method chaining?
40. How do you secure a C# application?

Experienced (40 Questions)


1. What is the Common Language Runtime (CLR)?
2. Explain the role of the .NET Framework.
3. How do you optimize performance in a C# application?
4. What are design patterns? Can you name a few?
5. Explain the repository pattern.
6. What is the difference between IEnumerable and ICollection?
7. How do you implement a multi-threaded application?
8. What is the Global Assembly Cache (GAC)?
9. What is garbage collection and how does it work?
10. Explain the differences between Task and ValueTask.
11. How do you manage application configuration in C#?
12. What are microservices and how can C# be used to implement them?
13. How do you handle security in a C# web application?
14. What is the [Link] Core pipeline?
15. Explain middleware in [Link] Core.
16. What are the differences between REST and SOAP?
17. How do you implement authentication and authorization in C#?
18. What is dependency inversion?
19. How do you work with Docker in C# applications?
20. What is the role of the Entity Framework Core?
21. Explain the concept of CQRS (Command Query Responsibility Segregation).
22. How do you perform dependency injection in [Link] Core?
23. What are the main benefits of using async/await in web applications?
24. How do you handle cross-origin requests in C#?
25. What are the differences between .NET Core and .NET Framework?
26. Explain the significance of ConfigureServices and Configure methods in [Link] Core.
27. How do you implement caching in a C# application?
28. What are background services in [Link] Core?
29. Explain how to use WebSockets in a C# application.
30. How do you ensure thread safety in a C# application?
31. What is middleware in [Link]?
32. How do you perform database migrations with Entity Framework?
33. What are the main types of testing (unit, integration, system) in C#?
34. Explain the role of attributes and reflection in C#.
35. How do you handle logging and error handling in a production environment?
36. What is a service-oriented architecture (SOA)?
37. Explain the use of the ConfigureAwait(false) method.
38. How do you set up and use Swagger for API documentation?
39. What are the principles of SOLID?
40. How do you integrate third-party libraries in a C# application?

Beginners (Q&A)
1. What is C#?
C# (pronounced "C-sharp") is a modern, object-oriented programming language developed
by Microsoft as part of its .NET initiative. It is designed for building a wide range of
applications, from web and desktop applications to mobile and cloud-based services. C# is a
statically typed language, meaning variable types are determined at compile time, which
helps in catching errors early in the development process.

C# supports features such as strong type checking, garbage collection, and inheritance,
making it a versatile choice for developers. It has a rich set of libraries and frameworks,
particularly with the .NET Framework and .NET Core, which provide a robust environment for
application development. C# also incorporates various programming paradigms, including
procedural, functional, and event-driven programming, which allows developers to choose the
best approach for their projects.

2. Explain the basic syntax of C#.


C# syntax is similar to other C-based languages, such as C++ and Java, making it relatively
easy for developers familiar with those languages to learn. The basic structure of a C#
program includes:

• Namespace Declaration: Used to organize code and avoid naming conflicts. For example,
namespace MyNamespace { }.
• Class Definition: C# is an object-oriented language, so the program structure revolves around
classes. A class is defined using the class keyword, such as class MyClass { }.
• Main Method: The entry point of a C# application, defined as static void Main(string[] args) { }.
This method is where the execution begins.
• Statements and Expressions: C# uses semicolons (;) to terminate statements. For example,
int a = 5;.
• Comments: C# supports single-line (// comment) and multi-line (/* comment */) comments for
documentation and code clarity.

3. What are data types in C#?


C# provides a variety of data types to store different kinds of information. These can be
broadly categorized into:

• Value Types: These types hold the actual value and include:

o Integral Types: int, long, short, byte, sbyte, uint, ulong.


o Floating-point Types: float, double, decimal.
o Other Types: char (for single characters) and bool (for true/false values).
• Reference Types: These types hold a reference to the actual data and include:

o Strings: A sequence of characters (string).


o Arrays: A collection of elements of the same type.
o Classes and Interfaces: Custom-defined types that can encapsulate data and
methods.
Additionally, C# supports nullable types, allowing value types to also represent null.

4. What is the difference between int and Int32?


In C#, int and Int32 are synonymous; both refer to a 32-bit signed integer. int is an alias
provided by C# for System.Int32, which is defined in the .NET framework. The primary
difference lies in readability and context:

• int: A keyword in C# that makes the code cleaner and easier to read. It’s commonly used in
variable declarations.
• Int32: A type defined in the .NET Framework, and it may be used when interacting with APIs
or libraries that utilize .NET types explicitly.
Using either in your code will yield the same functionality, but using int is generally preferred
for simplicity.

5. How do you declare a variable in C#?


In C#, a variable is declared by specifying its type followed by its name. The general syntax is:
type variableName;
For example, to declare an integer variable named age, you would write:
int age;
You can also initialize the variable at the time of declaration:
int age = 25;
C# allows multiple variables to be declared in one line, as long as they are of the same type:
int x = 10, y = 20, z = 30;
It’s important to note that variable names must follow certain rules: they must start with a letter
or underscore, can contain letters, digits, or underscores, and are case-sensitive.

6. What are operators in C#?


Operators in C# are special symbols that perform operations on variables and values. They
can be categorized into several types:

• Arithmetic Operators: Used for mathematical operations:

o + (addition)
o - (subtraction)
o * (multiplication)
o / (division)
o % (modulus)
• Relational Operators: Used to compare two values:

o == (equal to)
o != (not equal to)
o > (greater than)
o < (less than)
o >= (greater than or equal to)
o <= (less than or equal to)
• Logical Operators: Used for boolean logic:

o && (logical AND)


o || (logical OR)
o ! (logical NOT)
• Bitwise Operators: Operate on binary numbers:

o & (AND)
o | (OR)
o ^ (XOR)
o ~ (NOT)
• Assignment Operators: Used to assign values to variables:

o = (assign)
o +=, -=, *=, /=, %= (compound assignment)
Operators play a crucial role in controlling the flow of the program and performing
calculations.

7. Explain the difference between == and === in C#.


In C#, the == operator is used to compare two values for equality. However, C# does not
have a === operator, as seen in some other languages like JavaScript. Instead, C# uses ==
for both value types and reference types, but its behavior can differ based on the type of data
being compared:

Value Types: When comparing value types (like int, float, etc.), == compares the actual
values. For instance:
int a = 5;
int b = 5;
bool result = (a == b); // true
Reference Types: When comparing reference types (like objects and strings), == compares
the references (memory addresses) by default. However, many reference types (like strings)
override the == operator to compare the values instead:
string str1 = "hello";
string str2 = "hello";
bool result = (str1 == str2); // true, compares values
To explicitly compare references (the actual memory address), you can use the
[Link] method.

8. What is a namespace in C#?


A namespace in C# is a declarative region that provides a way to group related classes,
interfaces, structs, enums, and delegates. Namespaces help organize code and prevent
naming conflicts, especially in larger projects or when integrating multiple libraries.

To declare a namespace, you use the namespace keyword:


namespace MyApplication
{
class MyClass
{
// Class members go here
}
}
To access a class within a namespace, you can either fully qualify its name:
[Link] obj = new [Link]();
Or use a using directive at the top of your file:
using MyApplication;
MyClass obj = new MyClass();
Namespaces can be nested, and it’s common to organize them hierarchically, which aids in
code clarity and maintainability.

9. How do you handle exceptions in C#?


Exception handling in C# is managed using try, catch, finally, and throw keywords. This
mechanism allows developers to handle runtime errors gracefully, maintaining the program's
flow without crashing.

Try Block: The code that might throw an exception is placed inside a try block.
try
{
// Code that may throw an exception
int result = 10 / 0; // This will throw a DivideByZeroException
}
Catch Block: If an exception occurs, control is passed to the catch block, where you can
handle the exception appropriately.
catch (DivideByZeroException ex)
{
[Link]("Cannot divide by zero: " + [Link]);
}
Finally Block: This block is optional and executes whether an exception is thrown or not. It’s
commonly used for cleanup code, such as closing file streams.
finally
{
[Link]("This code runs regardless of exceptions.");
}
Throwing Exceptions: You can also throw exceptions intentionally using the throw keyword.
if (someCondition)
{
throw new InvalidOperationException("Something went wrong.");
}
10. What is a constructor?
A constructor in C# is a special method that is called when an instance of a class is created.
Its primary purpose is to initialize the object and set its initial state. Constructors have the
same name as the class and do not have a return type, not even void.

There are two main types of constructors in C#:

Default Constructor: A constructor that does not take any parameters. If no constructor is
defined, C# provides a default one automatically.
public class MyClass
{
public MyClass() // Default constructor
{
// Initialization code
}
}
Parameterized Constructor: A constructor that takes parameters to initialize an object with
specific values.
public class MyClass
{
public int Value;

public MyClass(int value) // Parameterized constructor


{
Value = value;
}
}
Constructors can also be overloaded, allowing multiple constructors with different parameters.
Additionally, a constructor can call another constructor within the same class using the this
keyword, facilitating code reuse.

Overall, constructors play a vital role in ensuring that objects are properly initialized and ready
for use immediately after they are created.

11. What is an array in C#?


An array in C# is a data structure that allows you to store a fixed-size sequence of elements
of the same type. Arrays provide a way to organize data in a single variable, enabling efficient
access and manipulation of multiple values. They are particularly useful when you need to
work with a collection of related items, such as a list of student grades or temperatures over a
week.

Arrays in C# are zero-indexed, meaning the first element is accessed at index 0. You can
declare and initialize an array in one line, or you can declare it first and then assign values:
// Declaration and initialization in one line
int[] numbers = { 1, 2, 3, 4, 5 };

// Declaration first
int[] moreNumbers = new int[5]; // Creates an array of size 5
moreNumbers[0] = 10; // Assigning values
moreNumbers[1] = 20;
You can also create multi-dimensional arrays, such as two-dimensional arrays (often used for
matrices):
int[,] matrix = new int[3, 3]; // A 3x3 matrix
Arrays have a fixed size; once created, their length cannot be changed. For dynamic sizing,
developers typically use collections like List<T>.

12. How do you create a list in C#?


In C#, a list is created using the List<T> class from the [Link]
namespace. A list provides a dynamic array that can grow and shrink in size as needed,
making it a versatile choice for managing collections of objects.

To create a list, you first need to include the namespace and then you can declare and
initialize a list:
using [Link];

List<int> numbers = new List<int>(); // Create an empty list of integers

// Adding elements
[Link](1);
[Link](2);
[Link](3);

// Initialize a list with values


List<string> fruits = new List<string> { "Apple", "Banana", "Cherry" };
Lists provide various methods for manipulating data, such as Add, Remove, Insert, and Sort,
allowing for easy management of elements.

13. What is the difference between List<T> and an array?


While both List<T> and arrays in C# are used to store collections of items, they have several
key differences:

• Size: Arrays have a fixed size, defined at the time of creation. Once created, the size cannot
change. In contrast, List<T> is dynamic, allowing you to add or remove elements at runtime
without needing to specify an initial size.
• Type Safety: Both arrays and List<T> are type-safe, meaning they enforce type constraints.
However, List<T> provides better flexibility with generics, allowing you to work with various
data types without boxing/unboxing.
• Functionality: List<T> comes with many built-in methods (like Add, Remove, Contains, and
Sort), making it more convenient for managing collections. Arrays require more manual
management for similar operations.
• Performance: Arrays can offer better performance for large data sets due to lower overhead,
especially for fixed-size collections. However, for frequent additions and removals, List<T> is
often more efficient and easier to use.

14. What are properties in C#?


Properties in C# are special methods (accessors) that provide a flexible mechanism to read,
write, or compute the values of private fields. They are a key aspect of encapsulation,
allowing control over how a field is accessed and modified.

A property consists of two accessors: get and set. The get accessor retrieves the value, while
the set accessor assigns a value. Here’s an example:
public class Person
{
private string name; // Private field

public string Name // Property


{
get { return name; }
set { name = value; }
}
}
You can also create auto-implemented properties, which simplify the syntax when no
additional logic is required:
public class Person
{
public string Name { get; set; } // Auto-implemented property
}
Properties enhance data encapsulation and help in maintaining the integrity of the data.
15. Explain the concept of encapsulation.
Encapsulation is one of the fundamental principles of object-oriented programming (OOP). It
refers to the bundling of data (attributes) and methods (functions) that operate on the data into
a single unit, typically a class. Encapsulation restricts direct access to some of an object's
components and protects the integrity of the object's state.

By using access modifiers (such as private, protected, and public), developers can control
how the data is accessed and modified. For example, you might expose a public method to
update a private field while keeping the field itself inaccessible from outside the class.
public class Account
{
private double balance;

public void Deposit(double amount)


{
if (amount > 0)
{
balance += amount;
}
}

public double GetBalance()


{
return balance;
}
}
In this example, balance is encapsulated; it can only be modified through the Deposit method,
ensuring that it cannot be set to an invalid value.

16. What is an interface in C#?


An interface in C# is a contract that defines a set of methods, properties, events, or indexers
without implementing them. Classes or structs that implement an interface must provide the
actual implementations for its members. Interfaces allow for a form of multiple inheritance in
C#, as a class can implement multiple interfaces.

Here’s an example of an interface and its implementation:


public interface IAnimal
{
void Speak(); // Method declaration
}

public class Dog : IAnimal


{
public void Speak() // Implementing the interface method
{
[Link]("Woof!");
}
}

public class Cat : IAnimal


{
public void Speak() // Implementing the interface method
{
[Link]("Meow!");
}
}
Interfaces are useful for defining capabilities that can be shared across different classes,
promoting code reusability and flexibility in programming.

17. What is the purpose of the using statement?


The using statement in C# serves two primary purposes:

Namespace Inclusion: It allows the use of types defined in a namespace without needing to
fully qualify their names. This makes code cleaner and more readable. For example:
using System;

public class MyClass


{
public void MyMethod()
{
[Link]("Hello, World!");
}
}
Resource Management: The using statement is also used for automatic resource
management, specifically for objects that implement the IDisposable interface. It ensures that
resources are disposed of properly when they are no longer needed. For instance, when
working with file streams:
using (StreamReader reader = new StreamReader("[Link]"))
{
string content = [Link]();
[Link](content);
} // The StreamReader is disposed of automatically here.
By utilizing the using statement, developers can prevent memory leaks and manage
resources efficiently.

18. How do you read from and write to a file in C#?


In C#, you can read from and write to files using classes provided by the [Link]
namespace. The two commonly used classes for file operations are StreamReader for
reading and StreamWriter for writing.

Writing to a File:
using [Link];

class Program
{
static void Main()
{
using (StreamWriter writer = new StreamWriter("[Link]"))
{
[Link]("Hello, World!");
[Link]("This is a file.");
} // The StreamWriter is disposed of automatically.
}
}
Reading from a File:
using [Link];

class Program
{
static void Main()
{
using (StreamReader reader = new StreamReader("[Link]"))
{
string line;
while ((line = [Link]()) != null)
{
[Link](line);
}
} // The StreamReader is disposed of automatically.
}
}
These operations are essential for handling file input and output, allowing applications to store
and retrieve data persistently.

19. What is the Main method?


The Main method is the entry point of a C# application. It is where the program starts
executing when you run a C# console application. The method can be defined in various
ways, but the most common signatures are:
static void Main(string[] args)
or
static int Main(string[] args)
The Main method can accept an array of strings as a parameter (args), which allows the
application to receive command-line arguments.

Here’s an example of a simple Main method:


class Program
{
static void Main(string[] args)
{
[Link]("Welcome to the application!");
}
}
In this example, when the application is executed, the message "Welcome to the application!"
will be displayed in the console.

20. How do you create a simple console application?


Creating a simple console application in C# is straightforward. You can use an IDE like Visual
Studio or Visual Studio Code, or you can use the .NET CLI (Command Line Interface).

Using Visual Studio:

1. Open Visual Studio and create a new project.


2. Select "Console App (.NET Core)" or "Console App (.NET Framework)" depending on your
preference.
3. Name your project and click "Create."
4. Visual Studio will generate a basic template for your console application, including the Main
method.
Using .NET CLI:

1. Open a command prompt or terminal.


Run the following command to create a new console application:
dotnet new console -n MyConsoleApp
Navigate to the project folder:
cd MyConsoleApp
Run the application with:
dotnet run
You can edit the generated [Link] file to include your code, and upon running the
application, it will execute the Main method, displaying output to the console.

21. What are access modifiers in C#?


Access modifiers in C# are keywords that define the accessibility of classes, methods,
properties, and other members. They control how and where these members can be
accessed from other parts of the code, thereby enforcing encapsulation. The main access
modifiers in C# are:

• public: Members are accessible from any other code in the same assembly or another
assembly that references it.
• private: Members are accessible only within the containing class or struct. This is the most
restrictive access level.
• protected: Members are accessible within their own class and by derived classes. It allows for
inheritance while keeping members hidden from other classes.
• internal: Members are accessible only within the same assembly, meaning they cannot be
accessed from outside the assembly but are accessible from any class in that assembly.
• protected internal: Members are accessible from the current assembly and from derived
classes in other assemblies.
These modifiers help in defining clear interfaces and protecting the internal state of classes.

22. What is the difference between public, private, protected,


and internal?
The differences between these access modifiers are primarily related to where members can
be accessed:

public: Members are visible and accessible from any other code. For example, a public class
or method can be accessed from any other class, regardless of the assembly.
public class PublicClass
{
public void PublicMethod() { }
}
private: Members are restricted to the containing class only. They cannot be accessed from
outside the class, including derived classes.
public class PrivateClass
{
private void PrivateMethod() { }
}
protected: Members can be accessed within the containing class and by any derived
classes. This allows derived classes to access the base class's protected members.
public class BaseClass
{
protected void ProtectedMethod() { }
}
internal: Members are accessible only within the same assembly. This is useful for limiting
access to classes and methods that should not be exposed outside the assembly.
internal class InternalClass
{
internal void InternalMethod() { }
}
These access levels provide flexibility in designing class interfaces while ensuring that
implementation details remain hidden.

23. Explain the concept of inheritance.


Inheritance is a fundamental principle of object-oriented programming (OOP) that allows one
class (the derived class) to inherit the properties and behaviors (methods) of another class
(the base class). This mechanism promotes code reusability and establishes a hierarchical
relationship between classes.

In C#, inheritance is implemented by using the : symbol. The derived class can extend or
override the base class's functionality, adding or modifying features as needed. Here's an
example:
public class Animal
{
public void Eat() { }
}

public class Dog : Animal // Dog inherits from Animal


{
public void Bark() { }
}
In this example, Dog inherits from Animal, meaning it can access the Eat method. Inheritance
allows for the creation of more specific classes based on general classes, supporting
polymorphism and better organization of code.

24. What is polymorphism?


Polymorphism is another core concept in OOP that allows objects of different types to be
treated as objects of a common super type. It enables a single interface to be used for
different underlying data types, facilitating code flexibility and reuse.

There are two main types of polymorphism in C#:


Compile-time polymorphism (Method Overloading): This occurs when multiple methods
have the same name but differ in parameters (type, number, or both). The appropriate
method is determined at compile time.
public class MathOperations
{
public int Add(int a, int b) { return a + b; }
public double Add(double a, double b) { return a + b; }
}
Run-time polymorphism (Method Overriding): This is achieved through inheritance and
interfaces, where a derived class provides a specific implementation of a method that is
already defined in its base class. The method to be invoked is determined at runtime based
on the object's type.
public class Animal
{
public virtual void Speak() { [Link]("Animal speaks"); }
}

public class Dog : Animal


{
public override void Speak() { [Link]("Woof!"); }
}
In this case, calling Speak on an Animal reference that actually points to a Dog object will
invoke the Dog's Speak method.

25. How do you implement method overloading in C#?


Method overloading in C# is the ability to create multiple methods with the same name but
different parameters within the same class. This allows methods to handle different types or
numbers of arguments, enhancing code clarity and usability.

To implement method overloading, simply define multiple methods with the same name but
varying parameter lists:
public class Calculator
{
public int Add(int a, int b) // Method with two integer parameters
{
return a + b;
}

public double Add(double a, double b) // Method with two double parameters


{
return a + b;
}

public int Add(int a, int b, int c) // Method with three integer parameters
{
return a + b + c;
}
}
In this example, the Add method is overloaded with three different signatures. The
appropriate method will be called based on the arguments passed when invoking it.

26. What is a static class?


A static class in C# is a class that cannot be instantiated and can only contain static members
(methods, properties, fields). Static classes are useful for grouping related methods that do
not require object state. They help in organizing code and providing utility functions.

To declare a static class, use the static keyword:


public static class MathUtilities
{
public static int Add(int a, int b) { return a + b; }
public static double Square(double number) { return number * number; }
}
You cannot create an instance of a static class:
MathUtilities math = new MathUtilities(); // This will cause a compilation error
Instead, you can call its static methods directly using the class name:
int sum = [Link](5, 10); // Calling a static method
27. How do you convert a string to an integer in C#?
In C#, you can convert a string to an integer using several methods, depending on whether
you want to handle potential errors gracefully. The most common methods are:

Using [Link]: This method converts a string representation of a number to its integer
equivalent. It throws an exception if the conversion fails.
string numberString = "123";
int number = [Link](numberString);
Using [Link]: This method attempts to convert a string to an integer and returns a
boolean indicating success or failure, making it safer to use when you're unsure if the string is
a valid number.
string numberString = "123";
int number;

if ([Link](numberString, out number))


{
[Link]("Conversion succeeded: " + number);
}
else
{
[Link]("Conversion failed.");
}
Using Convert.ToInt32: This method is another way to convert a string to an integer,
returning zero if the conversion fails. However, it does not throw exceptions for null strings.
string numberString = "123";
int number = Convert.ToInt32(numberString);
Each method has its use cases, and it's essential to choose based on the requirements of
your application.

28. What are collections in C#?


Collections in C# are classes that provide a way to store and manage groups of related
objects. They offer more flexibility and functionality than arrays, allowing dynamic resizing and
built-in methods for adding, removing, and searching for items.
The main types of collections in C# are found in the [Link] and
[Link] namespaces:

1. Generic Collections: These collections allow you to specify the type of objects they hold,
providing type safety and better performance. Common examples include:

o List<T>: A dynamic array.


o Dictionary<TKey, TValue>: A collection of key-value pairs.
o HashSet<T>: A collection of unique elements.
2. Non-Generic Collections: These collections can hold objects of any type, but they require
boxing/unboxing for value types. Examples include:

o ArrayList: A dynamic array (non-generic).


o Hashtable: A collection of key-value pairs (non-generic).
Collections make it easier to work with groups of data and are integral to many programming
tasks in C#.

29. What is a delegate?


A delegate in C# is a type that represents references to methods with a specific parameter list
and return type. Delegates are similar to function pointers in C/C++ but are type-safe. They
are primarily used for implementing event handling and callback methods.

To declare a delegate, use the delegate keyword:


public delegate void Notify(string message);
You can create an instance of a delegate and point it to a method with a matching signature:
public class Program
{
public static void ShowMessage(string message)
{
[Link](message);
}

public static void Main()


{
Notify notify = ShowMessage; // Assigning method to delegate
notify("Hello, Delegates!"); // Invoking the delegate
}
}
Delegates can also be combined to create multicast delegates, allowing multiple methods to
be invoked with a single delegate call.

30. What is an event in C#?


An event in C# is a special kind of delegate that provides a way for a class to notify other
classes or objects when something of interest occurs. Events are based on the publisher-
subscriber model, where the class that sends the notification is the publisher, and the classes
that receive the notification are subscribers.
Events are defined using the event keyword and are typically used in conjunction with
delegates:
public delegate void EventHandler(string message);

public class Publisher


{
public event EventHandler OnNotify;

public void Notify(string message)


{
OnNotify?.Invoke(message); // Notify subscribers
}
}
Subscribers can register their methods to listen for the event:
public class Subscriber
{
public void Subscribe(Publisher publisher)
{
[Link] += HandleNotification; // Subscribing to the event
}

private void HandleNotification(string message)


{
[Link]("Received message: " + message);
}
}
In this example, the Publisher class raises an event when it calls the Notify method, and the
Subscriber class can handle that event. Events provide a robust way to implement
asynchronous programming and decouple classes in C#.

31. How do you create a switch statement?


A switch statement in C# allows you to execute different code blocks based on the value of a
variable. It's often used as a cleaner alternative to multiple if-else statements when dealing
with many possible values.

Here's the basic syntax of a switch statement:


switch (expression)
{
case value1:
// Code to execute if expression equals value1
break;
case value2:
// Code to execute if expression equals value2
break;
default:
// Code to execute if expression doesn't match any case
break;
}
Here's an example:
int day = 3;

switch (day)
{
case 1:
[Link]("Monday");
break;
case 2:
[Link]("Tuesday");
break;
case 3:
[Link]("Wednesday");
break;
default:
[Link]("Invalid day");
break;
}
In this example, the output will be "Wednesday" because the value of day is 3. The break
statement is crucial as it prevents fall-through, meaning that the code will not execute the
subsequent cases unless explicitly stated.

32. What are tuples in C#?


Tuples in C# are a data structure that allows you to store multiple values of different types in a
single object. They are particularly useful for returning multiple values from a method without
needing to create a custom class or struct.

You can create a tuple using the Tuple class or by using the more modern syntax with value
tuples introduced in C# 7.0:

1. Using the Tuple class:


var tuple = new Tuple<int, string>(1, "One");
[Link]($"Item1: {tuple.Item1}, Item2: {tuple.Item2}");

2. Using value tuples:


var valueTuple = (Id: 1, Name: "One");
[Link]($"Id: {[Link]}, Name: {[Link]}");
Value tuples allow for named elements, enhancing readability. Tuples are immutable; once
created, their values cannot be changed.

33. What is the difference between a value type and a


reference type?
In C#, data types are categorized into two main categories: value types and reference types.

• Value Types:

o Store data directly.


o Examples include basic types like int, float, char, and structs (struct).
o When assigned to a new variable, a copy of the value is made.
int x = 10;
int y = x; // y is a copy of x, changes to y do not affect x.

• Reference Types:
o Store a reference to the actual data.
o Examples include classes (class), arrays, and strings.
o When assigned to a new variable, both variables refer to the same object in memory.
class Person
{
public string Name;
}

Person person1 = new Person();


[Link] = "Alice";
Person person2 = person1; // person2 references the same object as person1
[Link] = "Bob"; // Changes reflected in person1
Understanding these differences is essential for effective memory management and avoiding
unintended side effects in your code.

34. Explain the concept of a nullable type.


A nullable type in C# allows value types (like int, bool, etc.) to represent the normal range of
values plus an additional null value. This is particularly useful for representing missing or
undefined values, such as in database operations.

To declare a nullable type, use the ? operator:


int? nullableInt = null; // nullableInt can hold an integer or null
You can check if a nullable type has a value using the HasValue property or by using the null-
coalescing operator ??:
if ([Link])
{
[Link]([Link]);
}
else
{
[Link]("Value is null.");
}

int value = nullableInt ?? 0; // Use 0 if nullableInt is null


Nullable types are especially handy in scenarios where a value might be absent, such as
optional parameters or database fields.

35. What is garbage collection?


Garbage collection (GC) in C# is an automatic memory management feature that reclaims
memory occupied by objects that are no longer in use, preventing memory leaks and
optimizing resource usage.

The .NET runtime includes a garbage collector that periodically checks for objects that are no
longer referenced by any part of the application. Once identified, the memory used by these
objects is freed, making it available for future allocations.

Key aspects of garbage collection include:

• Generational collection: Objects are categorized into generations (0, 1, and 2) based on their
lifetime. Newly created objects start in Generation 0, and if they survive a garbage collection
cycle, they are promoted to Generation 1 and so on. This optimizes performance by focusing
on short-lived objects.
• Non-deterministic: Developers cannot predict when garbage collection will occur, though they
can manually trigger it using [Link](), which is generally discouraged due to performance
considerations.
Garbage collection helps developers focus on application logic without worrying excessively
about memory management.

36. How do you use a foreach loop?


The foreach loop in C# provides a simple and clean way to iterate over collections, arrays,
and other enumerable types without needing to manage the loop index manually. It enhances
readability and reduces the chance of errors.

Here’s the syntax for a foreach loop:


foreach (var item in collection)
{
// Code to execute for each item
}
Here’s an example using an array:
string[] fruits = { "Apple", "Banana", "Cherry" };

foreach (var fruit in fruits)


{
[Link](fruit);
}
This will output each fruit in the array. The foreach loop automatically handles the iteration,
making it easier to work with collections compared to traditional for loops.

37. What are lambda expressions?


Lambda expressions in C# are a concise way to represent anonymous methods. They
enable you to create inline functions that can be used primarily in places where you need a
delegate or an expression tree.

The syntax for a lambda expression is:


(parameters) => expression or { statements }
For example, here's how you might use a lambda expression with a list:
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };

// Using a lambda expression to filter even numbers


var evenNumbers = [Link](n => n % 2 == 0).ToList();
In this case, n => n % 2 == 0 is the lambda expression, which checks if a number is even.
Lambda expressions are widely used in LINQ queries and event handling.

38. How do you handle multiple exceptions in C#?


In C#, you can handle multiple exceptions by using multiple catch blocks after a single try
block. Each catch block can handle a specific exception type, allowing for granular error
handling.
Here’s an example:
try
{
// Code that may throw exceptions
int result = 10 / [Link]("0"); // This will throw an exception
}
catch (DivideByZeroException ex)
{
[Link]("Cannot divide by zero: " + [Link]);
}
catch (FormatException ex)
{
[Link]("Invalid format: " + [Link]);
}
catch (Exception ex) // General catch block
{
[Link]("An unexpected error occurred: " + [Link]);
}
In this example, specific exceptions (DivideByZeroException and FormatException) are
handled with dedicated catch blocks, while a general catch block handles any other
exceptions. This allows for more specific responses to different error conditions.

39. What is LINQ?


LINQ (Language Integrated Query) is a powerful feature in C# that allows developers to
query collections (like arrays, lists, and databases) in a more readable and expressive
manner using syntax that is integrated into the C# language.

LINQ provides a consistent way to query various data sources, regardless of their underlying
structure. You can use LINQ with:

• LINQ to Objects: Queries on in-memory collections.


• LINQ to SQL: Queries on SQL databases.
• LINQ to XML: Queries on XML data.
Here’s an example of using LINQ to filter a list of numbers:
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6 };

// Using LINQ to filter even numbers


var evenNumbers = [Link](n => n % 2 == 0).ToList();

foreach (var num in evenNumbers)


{
[Link](num); // Outputs: 2, 4, 6
}
LINQ enhances productivity by allowing developers to express complex queries in a clear,
concise manner, improving code maintainability.

40. Explain the difference between string and StringBuilder.


string and StringBuilder are both used to handle text in C#, but they have different
characteristics and use cases:
• string:

o Immutable: Once created, a string object cannot be changed. Any modification creates
a new string instance.
o Suitable for scenarios with a small number of changes.
string str = "Hello";
str += " World"; // Creates a new string, "Hello World"

• StringBuilder:

o Mutable: StringBuilder allows you to modify the string in place without creating new
objects. This is more memory-efficient for operations involving many changes.
o Ideal for scenarios involving extensive string manipulation (e.g., concatenation in
loops).
StringBuilder sb = new StringBuilder("Hello");
[Link](" World"); // Modifies the existing instance
string result = [Link](); // Convert back to string
Using StringBuilder in scenarios with multiple concatenations can greatly enhance
performance by reducing memory allocation overhead.

Intermediate (Q&A)
1. What are generics in C#?
Generics in C# allow you to define classes, interfaces, and methods with a placeholder for the
type of data they store or manipulate. This means you can create reusable code components
that work with any data type without sacrificing type safety.

Benefits of Generics:

• Type Safety: Generics ensure that type checks are performed at compile time, reducing
runtime errors.
• Code Reusability: You can create methods and classes that can operate on any data type.
• Performance: Using generics can reduce the need for boxing and unboxing operations when
dealing with value types, which enhances performance.
Example: Here’s a simple generic class:
public class GenericList<T>
{
private T[] items = new T[10];
private int count = 0;

public void Add(T item)


{
items[count++] = item;
}

public T Get(int index)


{
return items[index];
}
}
// Usage
var intList = new GenericList<int>();
[Link](1);
[Link](2);

var stringList = new GenericList<string>();


[Link]("Hello");
[Link]("World");
2. Explain the async and await keywords.
The async and await keywords in C# are used to facilitate asynchronous programming,
allowing developers to write code that can perform potentially long-running operations without
blocking the main thread.

• async Keyword: This is applied to a method to indicate that it contains asynchronous


operations. An async method can return a Task, Task<T>, or void (for event handlers).
• await Keyword: This is used before a call to an asynchronous method. It tells the compiler to
pause the execution of the async method until the awaited task is complete, allowing the
thread to do other work in the meantime.
Example:
public async Task<string> DownloadDataAsync(string url)
{
using (var client = new HttpClient())
{
var response = await [Link](url);
return response;
}
}
In this example, DownloadDataAsync will not block the calling thread while waiting for the
web request to complete, improving responsiveness in applications.

3. What is dependency injection?


Dependency Injection (DI) is a design pattern used in software development to achieve
Inversion of Control (IoC) between classes and their dependencies. Rather than a class
creating its own dependencies, they are provided to the class externally, typically through the
constructor.

Benefits of Dependency Injection:

• Decoupling: Classes are less dependent on specific implementations, making them easier to
test and maintain.
• Flexibility: Dependencies can be easily swapped out with minimal changes to the class using
them.
• Testability: Makes unit testing easier since you can inject mock dependencies.
Example:
public interface IMessageService
{
void SendMessage(string message);
}
public class EmailService : IMessageService
{
public void SendMessage(string message)
{
// Code to send email
}
}

public class Notification


{
private readonly IMessageService _messageService;

public Notification(IMessageService messageService) // Dependency Injection


{
_messageService = messageService;
}

public void Notify(string message)


{
_messageService.SendMessage(message);
}
}
4. How do you implement interfaces in C#?
In C#, an interface is a contract that defines a set of methods and properties without
implementing them. Classes that implement the interface must provide implementations for
all its members.

Defining an Interface:
public interface IAnimal
{
void Speak();
}
Implementing an Interface:
public class Dog : IAnimal
{
public void Speak()
{
[Link]("Woof!");
}
}

public class Cat : IAnimal


{
public void Speak()
{
[Link]("Meow!");
}
}
When a class implements an interface, it guarantees that it provides implementations for all
methods defined in that interface. This enables polymorphism, allowing you to use interface
types interchangeably.

5. What is reflection?
Reflection is a feature in C# that allows you to inspect the metadata of types at runtime. This
includes accessing information about classes, methods, properties, and other members, even
if you don’t have compile-time access to them.

Common Uses of Reflection:

• Inspecting attributes and metadata.


• Creating instances of types dynamically.
• Invoking methods dynamically.
• Accessing private members.
Example:
Type type = typeof(Dog);
[Link]("Methods of Dog class:");
foreach (var method in [Link]())
{
[Link]([Link]);
}
This example retrieves and prints all methods defined in the Dog class using reflection.

6. Explain the concept of attributes in C#.


Attributes in C# are a way to add metadata to your code elements (classes, methods,
properties, etc.). They provide additional information that can be retrieved at runtime via
reflection.

Attributes are defined by creating a class that derives from [Link] and can be
applied to various elements of your code.

Example:
[AttributeUsage([Link])]
public class DeveloperAttribute : Attribute
{
public string Name { get; }
public DeveloperAttribute(string name)
{
Name = name;
}
}

[Developer("Alice")]
public class SampleClass
{
}
In this example, the DeveloperAttribute is applied to SampleClass, adding metadata about
the developer’s name. You can retrieve this information using reflection.

7. How does the IDisposable interface work?


The IDisposable interface is used to provide a mechanism for releasing unmanaged
resources (like file handles, database connections, etc.) when they are no longer needed. It
includes a single method, Dispose(), which is called to free resources.
Implementing IDisposable: When a class implements IDisposable, it should provide the
Dispose() method to clean up resources:
public class ResourceHolder : IDisposable
{
private bool disposed = false; // Track whether resources are disposed

public void Dispose()


{
Dispose(true);
[Link](this); // Prevent finalizer from being called
}

protected virtual void Dispose(bool disposing)


{
if (!disposed)
{
if (disposing)
{
// Free managed resources
}
// Free unmanaged resources

disposed = true;
}
}

~ResourceHolder() // Finalizer
{
Dispose(false);
}
}
Using IDisposable is essential for managing resource cleanup effectively, especially in
scenarios with unmanaged resources.

8. What are extension methods?


Extension methods allow you to add new methods to existing types without modifying the
original type or creating a new derived type. They are defined as static methods in static
classes and use the this keyword in the first parameter to specify the type being extended.

Example:
public static class StringExtensions
{
public static bool IsNullOrEmpty(this string str)
{
return [Link](str);
}
}

// Usage
string name = null;
bool isEmpty = [Link](); // Calling the extension method
In this example, the IsNullOrEmpty method extends the string type, allowing you to call it as if
it were a method on string instances.

9. How do you handle threading in C#?


Threading in C# allows multiple threads to run concurrently, enabling applications to perform
tasks simultaneously. The [Link] namespace provides classes for creating and
managing threads.

You can create a new thread using the Thread class:


Thread thread = new Thread(new ThreadStart(MyMethod));
[Link]();

void MyMethod()
{
// Code to run on the new thread
}
Alternatively, you can use the Task class from the [Link] namespace,
which provides a higher-level abstraction for working with threads:
[Link](() => MyMethod());
Using Task is often preferred for its ease of use and better integration with async
programming.

10. What is the difference between Task and Thread?


The Task and Thread classes in C# are both used for asynchronous programming, but they
serve different purposes and have different characteristics:

• Thread:

o Represents a single thread of execution.


o Requires more overhead to manage, as you have to handle thread creation,
scheduling, and lifecycle.
o Suitable for long-running or CPU-bound operations.
Thread thread = new Thread(() => { /* Work */ });
[Link]();

• Task:

o Represents an asynchronous operation that can be run on a thread pool thread.


o Provides better resource management, as it automatically handles thread
management and scheduling.
o Ideal for I/O-bound operations and tasks that can benefit from parallelism.
Task task = [Link](() => { /* Work */ });
In summary, use Task for asynchronous programming where you want to simplify
concurrency management, and use Thread when you need fine-grained control over thread
execution.

11. Explain the lock statement.


The lock statement in C# is used to ensure that a block of code runs exclusively by one
thread at a time. It helps to prevent race conditions when multiple threads attempt to access
shared resources simultaneously.
Syntax:
lock (object)
{
// Code to execute
}
Example:
private static readonly object _lock = new object();
private static int _counter = 0;

public void IncrementCounter()


{
lock (_lock)
{
_counter++;
}
}
In this example, when one thread is executing the code within the lock block, other threads
attempting to enter this block will be blocked until the first thread exits. This ensures thread
safety when incrementing the _counter variable.

12. What is the volatile keyword?


The volatile keyword in C# is used to indicate that a field can be accessed by multiple
threads. It tells the compiler and the runtime not to cache the value of that field in a register or
optimize access to it, ensuring that every read/write operation goes directly to memory.

Use Case: The volatile keyword is typically used for simple fields that need to be accessed
across threads without locking. However, it should be used with caution, as it does not
provide complete thread safety.

Example:
private volatile bool _isRunning;

public void Stop()


{
_isRunning = false;
}

public void Start()


{
while (_isRunning)
{
// Do work
}
}
In this example, _isRunning is marked as volatile to ensure that all threads see the latest
value without caching.

13. How do you work with JSON in C#?


In C#, working with JSON is commonly done using libraries like [Link] ([Link])
or the built-in [Link] library (available in .NET Core 3.0 and later). These libraries
provide methods for serializing and deserializing JSON data.
Example with [Link]:
using [Link];

public class Person


{
public string Name { get; set; }
public int Age { get; set; }
}

// Serialization
var person = new Person { Name = "Alice", Age = 30 };
string json = [Link](person);

// Deserialization
var deserializedPerson = [Link]<Person>(json);
Example with [Link]:
using [Link];

// Serialization
var person = new Person { Name = "Alice", Age = 30 };
string json = [Link](person);

// Deserialization
var deserializedPerson = [Link]<Person>(json);
Both libraries make it easy to convert between C# objects and JSON strings, allowing for
easy data exchange in web applications and APIs.

14. What is a lambda expression and how is it used?


A lambda expression is a concise way to represent anonymous methods in C#. It allows you
to define inline functions that can be passed as arguments or used to create delegates.

Syntax:
(parameters) => expression
Example:
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };

// Using a lambda expression with LINQ


var evenNumbers = [Link](n => n % 2 == 0).ToList();
In this example, n => n % 2 == 0 is a lambda expression that checks if a number is even.
Lambda expressions are often used with LINQ for filtering, mapping, and reducing collections.

15. What are anonymous types?


Anonymous types in C# allow you to create simple, unnamed types on the fly, primarily for
grouping a set of related properties. They are defined using the new keyword and can contain
read-only properties.

Example:
var person = new
{
Name = "Alice",
Age = 30
};

// Accessing properties
[Link]($"Name: {[Link]}, Age: {[Link]}");
Anonymous types are particularly useful when you need to quickly encapsulate data without
creating a formal class. However, they can only be used in the scope where they are created,
and you cannot pass them as parameters or return them from methods.

16. How do you implement asynchronous programming in


C#?
Asynchronous programming in C# is typically implemented using the async and await
keywords. This allows methods to perform time-consuming operations without blocking the
calling thread, enhancing responsiveness, especially in UI applications.

Example:
public async Task<string> FetchDataAsync(string url)
{
using (var client = new HttpClient())
{
string result = await [Link](url);
return result;
}
}

// Calling the asynchronous method


var data = await FetchDataAsync("[Link]
In this example, the FetchDataAsync method fetches data from a URL asynchronously. The
await keyword is used to pause the execution until the data is received, allowing the calling
thread to perform other tasks in the meantime.

17. What is the purpose of the async keyword?


The async keyword is used to declare an asynchronous method in C#. It allows the method
to contain await expressions, which indicate that the method may perform an asynchronous
operation. When an async method is called, it returns a Task or Task<T>, representing the
ongoing operation.

Key Points:

• It simplifies the writing of asynchronous code by allowing you to write code that looks
synchronous while actually being asynchronous.
• It helps improve application responsiveness, particularly in UI applications, by preventing
blocking calls.
Example:
public async Task<int> CalculateAsync()
{
await [Link](1000); // Simulating a delay
return 42;
}
18. How can you prevent a class from being instantiated?
You can prevent a class from being instantiated by using a private constructor. This is often
used in singleton patterns or when creating static classes.

Example of a Static Class:


public static class Utility
{
public static void DoSomething() { }
}
Example of a Singleton:
public class Singleton
{
private static Singleton _instance;

private Singleton() { } // Private constructor

public static Singleton Instance


{
get
{
if (_instance == null)
{
_instance = new Singleton();
}
return _instance;
}
}
}
In this singleton example, the class cannot be instantiated from outside the class itself,
ensuring that only one instance exists.

19. Explain the concept of a singleton pattern.


The singleton pattern is a design pattern that restricts a class to a single instance and
provides a global point of access to that instance. It is commonly used for managing shared
resources, such as configuration settings or database connections.

Implementation Steps:

1. Make the constructor private to prevent direct instantiation.


2. Create a static property or method to access the single instance.
3. Optionally, implement lazy initialization to create the instance only when it is needed.
Example:
public class Logger
{
private static Logger _instance;

private Logger() { }

public static Logger Instance


{
get
{
if (_instance == null)
{
_instance = new Logger();
}
return _instance;
}
}

public void Log(string message)


{
[Link](message);
}
}
In this example, Logger can only be instantiated once, and you can access it through
[Link].

20. What is the difference between abstract classes and


interfaces?
Both abstract classes and interfaces are used to define contracts for classes in C#, but they
have distinct characteristics and use cases:

• Abstract Class:

o Can contain implementation of methods (both abstract and concrete).


o Can have fields, constructors, and access modifiers.
o A class can inherit from only one abstract class (single inheritance).
public abstract class Animal
{
public abstract void Speak(); // Abstract method
public void Sleep() { } // Concrete method
}

• Interface:

o Cannot contain implementation (C# 8.0 introduced default implementations, but it’s
limited).
o Cannot have fields or constructors, only method signatures and properties.
o A class can implement multiple interfaces (multiple inheritance).
public interface IAnimal
{
void Speak();
}
Usage:

• Use an abstract class when you want to provide some shared behavior or state.
• Use an interface when you want to define a contract that multiple classes can implement.

21. How do you implement the observer pattern in C#?


The observer pattern is a behavioral design pattern that defines a one-to-many dependency
between objects so that when one object (the subject) changes state, all its dependents
(observers) are notified and updated automatically.
Implementation Steps:

1. Define a subject interface that includes methods for attaching, detaching, and notifying
observers.
2. Create concrete implementations of the subject.
3. Define an observer interface with an update method.
4. Implement concrete observers that respond to updates from the subject.
Example:
// Subject Interface
public interface ISubject
{
void Attach(IObserver observer);
void Detach(IObserver observer);
void Notify();
}

// Observer Interface
public interface IObserver
{
void Update(string message);
}

// Concrete Subject
public class NewsPublisher : ISubject
{
private List<IObserver> _observers = new List<IObserver>();
private string _news;

public void Attach(IObserver observer) => _observers.Add(observer);


public void Detach(IObserver observer) => _observers.Remove(observer);
public void Notify()
{
foreach (var observer in _observers)
{
[Link](_news);
}
}

public void PublishNews(string news)


{
_news = news;
Notify();
}
}

// Concrete Observer
public class NewsSubscriber : IObserver
{
public void Update(string message) => [Link]($"Received news:
{message}");
}

// Usage
var publisher = new NewsPublisher();
var subscriber = new NewsSubscriber();

[Link](subscriber);
[Link]("New design pattern article released!");
22. What are the main differences between IEnumerable and
IQueryable?
IEnumerable and IQueryable are both interfaces used for querying collections in C#, but they
have different purposes and behaviors:

• IEnumerable:

o Represents a forward-only cursor for a collection and is best for in-memory collections
(like arrays or lists).
o Queries are executed in-memory after the collection is retrieved.
o Suitable for LINQ to Objects.
IEnumerable<int> numbers = new List<int> { 1, 2, 3 }.Where(n => n > 1);

• IQueryable:

o Designed for querying data from remote sources (like databases) through LINQ.
o Supports deferred execution and translates queries into a format suitable for the
underlying data source (e.g., SQL).
o Suitable for LINQ to SQL or Entity Framework.
IQueryable<int> queryableNumbers = [Link](n => n > 1);
In summary, use IEnumerable for in-memory collections and IQueryable for querying data
from an external data source.

23. How do you handle large data sets in C#?


Handling large data sets in C# requires strategies to manage memory and optimize
performance. Here are some common techniques:

1. Paging: Retrieve a subset of data (e.g., 100 records at a time) rather than loading the entire
dataset into memory. This can be done using Skip and Take methods in LINQ.
var pageSize = 100;
var pageNumber = 1;
var pagedData = [Link]((pageNumber - 1) *
pageSize).Take(pageSize).ToList();

2. Streaming: Use data streaming for processing data incrementally instead of loading it all at
once. For example, when reading from a file or database, you can process records one at a
time.
3. Asynchronous Processing: Use asynchronous methods (like async and await) to improve
responsiveness when loading or processing large datasets.
4. Batch Processing: Process data in batches instead of all at once to reduce memory footprint.
5. Data Compression: Use compression techniques when storing or transmitting large datasets
to save space.

24. What is a circular reference?


A circular reference occurs when two or more objects reference each other, creating a cycle
in the object graph. This can lead to memory leaks and issues with garbage collection if not
handled properly.

Example:
public class A
{
public B BReference { get; set; }
}

public class B
{
public A AReference { get; set; }
}

// Usage
var a = new A();
var b = new B();
[Link] = b;
[Link] = a;
In this example, A has a reference to B, and B has a reference back to A, creating a circular
reference. To avoid issues, you can use weak references or design patterns like Dependency
Injection to manage object lifetimes.

25. Explain the use of yield in C#.


The yield keyword is used in C# to create an iterator, which allows you to define a method
that can return a sequence of values one at a time, rather than all at once. This is useful for
working with large collections or streams of data where you want to minimize memory usage.

Example:
public IEnumerable<int> GetNumbers(int count)
{
for (int i = 0; i < count; i++)
{
yield return i; // Return each value one at a time
}
}

// Usage
foreach (var number in GetNumbers(10))
{
[Link](number);
}
In this example, the GetNumbers method returns an IEnumerable<int> and produces
numbers one by one, allowing the calling code to process each number without needing to
load all of them into memory simultaneously.

You might also like