C# .net scenario-based interview questions for experienced and freshers.
C# is a high-level programming language that blends the ease of use of Java with the power and performance of C++. It’s commonly used for developing Windows applications, web services, web applications, and mobile applications.
C# (pronounced "C-sharp") is a versatile, object-oriented programming language developed by Microsoft, designed for building a wide range of robust applications. It runs on the .NET framework, an open-source, cross-platform framework also developed by Microsoft, which provides a runtime environment for applications and a vast library of pre-built functionality. Here's a detailed, SEO-friendly explanation of C# .NET and why it stands out in the development world.
C# .NET interview questions and answers suitable for experienced developers, with brief explanations. These questions cover a broad range of advanced topics in C# and .NET, focusing on key concepts, design patterns, and best practices.
1. What is the difference between const, readonly, and static in C#?
Answer:
const: Constants are compile-time constants. They cannot be changed after declaration and are implicitly static.
readonly: The value of a readonly field can be assigned at runtime, but only in the constructor or during variable declaration.
static: static members belong to the type itself rather than instances of the type. Static variables retain their values across all instances.
2. What is the use of async and await in C#?
Answer:
async and await are used to write asynchronous methods in C#. The async keyword indicates that the method is asynchronous and can contain await expressions. await pauses the method execution until the awaited task completes, without blocking the calling thread. Asynchronous programming enhances performance, especially for I/O-bound tasks.
3. Explain the SOLID principles in C#.
Answer:
S: Single Responsibility Principle (SRP) – A class should have only one reason to change.
O: Open/Closed Principle (OCP) – A class should be open for extension but closed for modification.
L: Liskov Substitution Principle (LSP) – Derived classes should be substitutable for their base classes.
I: Interface Segregation Principle (ISP) – No client should be forced to depend on methods it does not use.
D: Dependency Inversion Principle (DIP) – High-level modules should not depend on low-level modules; both should depend on abstractions.
4. What is the difference between IEnumerable, IQueryable, and List in C#?
Answer:
IEnumerable: Returns data from in-memory collections, supports deferred execution, and can only perform forward iteration.
IQueryable: Used for querying out-of-memory data sources like databases, supporting LINQ queries with deferred execution and better performance for large datasets.
List: A generic collection that provides fast indexed access, stores data in memory, and is more flexible for frequent item additions and deletions.
5. What is a Delegate in C# and how does it differ from an Event?
Answer:
A delegate is a type-safe function pointer that holds references to methods with a specific signature. Delegates can invoke multiple methods (multicast delegates). An event is a special kind of delegate that restricts direct invocation. It allows methods to be subscribed and unsubscribed, providing a publish/subscribe mechanism.
6. What is garbage collection in .NET?
Answer:
Garbage Collection (GC) is an automatic memory management feature in .NET. It deallocates objects that are no longer referenced by the application, freeing memory. The GC works in generations (0, 1, and 2), with Gen 0 being for short-lived objects and Gen 2 for long-lived objects. It optimizes performance by cleaning up unused objects periodically.
7. Explain the difference between Task and Thread in C#.
Answer:
Thread: Represents an actual OS thread, which can be used for multithreading. It's more expensive in terms of resource usage.
Task: Represents an asynchronous operation and is part of the Task Parallel Library (TPL). Tasks are higher-level abstractions that can use the thread pool to manage threads more efficiently. They provide better control over asynchronous workflows.
8. What are Generics in C#, and why are they useful?
Answer:
Generics allow you to define type-safe data structures without committing to actual data types. This enhances code reusability, type safety, and performance by reducing the need for boxing/unboxing in collections. You can create classes, methods, interfaces, and delegates with generics. For example: List<T>, Dictionary<TKey, TValue>.
9. What is the difference between Finalizer and Dispose method in C#?
Answer:
Finalizer (~ClassName): Called by the GC before an object is reclaimed. It is non-deterministic and should only be used for resource cleanup if Dispose() isn’t called.
Dispose: Part of the IDisposable interface and used to release unmanaged resources deterministically. It is called explicitly by developers or implicitly via a using statement.
10. Explain the concept of Dependency Injection (DI) in .NET.
Answer:
Dependency Injection (DI) is a design pattern that helps implement the Inversion of Control (IoC) principle. It allows classes to receive their dependencies via constructors, properties, or methods, instead of creating them internally. In .NET, DI is built-in and allows for better testability, modularity, and decoupled design.
11. What is the difference between override, virtual, and new keywords in C#?
Answer:
virtual: Used to mark a method in the base class as "overrideable".
override: Used in a derived class to modify the behavior of a virtual method in the base class.
new: Used to hide a base class method in the derived class, rather than overriding it.
12. What are Extension Methods in C#?
Answer:
Extension Methods allow you to add new methods to existing types without modifying the original type. They are static methods in static classes but are called as if they were instance methods of the extended type. For example, adding a custom method to string without modifying its source code.
13. What is async/await Deadlock and how can it be avoided?
Answer:
An async/await deadlock occurs when an await on an asynchronous task blocks the main thread (usually in UI or ASP.NET apps) and prevents the continuation of the task from executing. To avoid this, use ConfigureAwait(false) to indicate that the continuation does not need to run on the original context.
14. What is Reflection in C#?
Answer:
Reflection is the ability of a program to inspect and manipulate its own structure (metadata) at runtime. It allows you to obtain information about assemblies, modules, types, and members dynamically. Reflection is used for various tasks like dynamically creating instances, invoking methods, or accessing attributes.
15. Explain the async and await keywords in .NET. How do they work internally?
Answer:
The async keyword marks a method as asynchronous, while await pauses the execution of the method until the awaited task completes. Internally, the async method creates a state machine to track its progress, and the await operator allows the continuation of the method after the task is completed, without blocking threads.
16. What is the difference between throw and throw ex in C#?
Answer:
throw: Re-throws the current exception while preserving the original stack trace, which is useful for debugging.
throw ex: Throws the exception with a new stack trace, which may obscure the original error location.
17. What is a Singleton design pattern and how do you implement it in C#?
Answer:
The Singleton pattern ensures that a class has only one instance and provides global access to that instance. It can be implemented by:
Making the constructor private.
Using a static method/property to provide access to the instance.
public class Singleton
{
private static readonly Singleton _instance = new Singleton();
private Singleton() { }
public static Singleton Instance => _instance;
}
18. What is yield in C#, and when would you use it?
Answer:
The yield keyword is used in an iterator method to return each element one at a time. Instead of creating a collection and returning it, yield allows the method to return values lazily, improving memory usage and performance for large datasets. Example:
public IEnumerable<int> GetNumbers()
{
for (int i = 1; i <= 10; i++)
{
yield return i;
}
}
19. Explain boxing and unboxing in C#.
Answer:
Boxing: Converting a value type (e.g., int) to a reference type (e.g., object), which involves wrapping the value in an object.
Unboxing: Extracting the value type from the object, which requires explicit casting. Boxing incurs a performance cost due to heap allocation, so it should be minimized.
20. What is LINQ, and how does it improve querying in C#?
Answer:
LINQ (Language Integrated Query) allows querying collections in a declarative way using SQL-like syntax in C#. It improves code readability, reduces errors, and supports multiple data sources like databases (LINQ to SQL), in-memory collections (LINQ to Objects), XML (LINQ to XML), and more. LINQ uses deferred execution, meaning the query is executed when iterated over.
These advanced C# .NET interview questions will help you prepare for roles that require deep knowledge of .NET, object-oriented principles, and best coding practices. The answers are concise to cater to experienced professionals who are familiar with C# concepts.
21. What is Dependency Injection (DI) in C#? How is it implemented in .NET Core?
Answer:
Dependency Injection (DI) is a design pattern that promotes loose coupling between components by injecting dependencies into a class rather than having the class instantiate them. In .NET Core, DI is built-in and can be implemented by registering services in the Startup.cs file using methods like AddTransient(), AddScoped(), and AddSingleton() in the ConfigureServices() method.
22. What is the difference between StringBuilder and String in C#?
Answer:
String: Immutable, meaning once created, it cannot be modified. Every change creates a new string object, leading to performance overhead in scenarios with many modifications.
StringBuilder: Mutable and more efficient for frequent string manipulations because it doesn’t create new objects for each modification. It's ideal for concatenating large strings in loops.
23. What are the different types of collections in C#?
Answer:
Array: Fixed-size collection of elements of the same type.
List<T>: Resizable collection of strongly-typed elements.
Dictionary<TKey, TValue>: Collection of key/value pairs.
HashSet<T>: Collection of unique elements without duplicates.
Queue<T>: FIFO (First-In-First-Out) collection.
Stack<T>: LIFO (Last-In-First-Out) collection.
24. Explain how memory is managed in C# with regard to the stack and the heap.
Answer:
Stack: Stores value types and function call information (local variables). The memory allocation here is fast and managed automatically, but it is limited in size.
Heap: Stores reference types (objects, strings) and is larger than the stack. The .NET garbage collector manages memory in the heap, cleaning up objects that are no longer in use.
25. What is the difference between IEnumerable<T> and IList<T> in C#?
Answer:
IEnumerable<T>: Represents a read-only collection that can be enumerated using a foreach loop. It does not support indexing or modifying elements.
IList<T>: Inherits from IEnumerable<T> but adds more functionality, such as indexing, adding, and removing elements. It supports read/write access.
26. What is Reflection and why would you use it in C#?
Answer:
Reflection is the ability to inspect metadata about types at runtime, including methods, properties, and attributes. It allows you to dynamically create instances, invoke methods, or access fields and properties. It’s often used for creating frameworks, tools like serializers, and performing operations on types unknown at compile time.
27. What is the difference between Task.Run() and Task.Factory.StartNew() in C#?
Answer:
Task.Run(): Simplified way to run a task on a thread pool for background processing. It should be used for CPU-bound operations and is recommended in most cases.
Task.Factory.StartNew(): More flexible, allowing you to specify task creation options, task scheduler, and more control over scheduling. It can be used for more advanced scenarios but requires careful use.
28. What is AutoMapper, and when would you use it in .NET?
Answer:
AutoMapper is a library in .NET that simplifies object-to-object mapping, particularly useful in situations where you need to map properties between two objects, such as mapping a DTO (Data Transfer Object) to a domain model. It reduces boilerplate code by automatically handling mappings based on property names.
29. What are nullable types in C#, and why are they useful?
Answer:
Nullable types (e.g., int?) allow value types (like int, bool, DateTime) to represent null. They are useful when working with databases or scenarios where a value might be missing or undefined. The HasValue property checks whether the nullable type contains a value, and Value retrieves the value if it exists.
30. Explain the lock statement in C#. Why is it used?
Answer:
The lock statement is used to ensure that a block of code runs exclusively by a single thread at a time, preventing race conditions in multithreading scenarios. When one thread enters a lock block, other threads are blocked from executing the code inside that block until the first thread exits. The lock ensures that shared resources (like a static field or list) are accessed in a thread-safe manner.
31. What is the difference between early binding and late binding in C#?
Answer:
Early binding: The method, property, or object is determined at compile time. The compiler checks for errors and ensures type safety (e.g., calling a method on an object of a known type).
Late binding: The method, property, or object is determined at runtime using Reflection or dynamic types. Late binding is more flexible but can lead to runtime errors if the method doesn’t exist or the types don’t match.
32. Explain IDisposable and the using statement in C#.
Answer:
IDisposable is an interface that defines the Dispose() method for releasing unmanaged resources (e.g., file handles, database connections). The using statement ensures that Dispose() is called automatically when the object goes out of scope, making resource management easier and more reliable.
33. What is the difference between Task.Wait() and await in C#?
Answer:
Task.Wait(): Blocks the current thread until the task is complete, leading to potential performance issues, particularly in UI applications.
await: Does not block the current thread; instead, it asynchronously waits for the task to complete and resumes execution on the same thread context. It is the preferred way to handle asynchronous operations.
34. What is the difference between Abstract Classes and Interfaces in C#?
Answer:
Abstract Classes: Can have method implementations and state (fields). They are used to provide a common base class that derived classes can share.
Interfaces: Define a contract with no implementation. They allow classes to implement multiple behaviors, as C# supports multiple interfaces but only single inheritance of abstract classes.
35. What are Expression Trees in C#?
Answer:
Expression Trees represent code in a tree-like structure, where each node is an expression (like a method call or binary operation). They are used in LINQ to translate queries to other formats (e.g., SQL), and they enable dynamic creation and execution of code at runtime. Expression trees provide a way to inspect and manipulate code as data.
36. What is an Indexer in C#?
Answer:
An indexer allows an object to be indexed in the same way as an array. It is defined using the this keyword and allows an instance of a class to be accessed using array-like syntax. Indexers are useful for classes that represent collections or data structures.
public class SampleCollection<T>
{
private T[] arr = new T[100];
public T this[int index]
{
get { return arr[index]; }
set { arr[index] = value; }
}
}
37. What is Polymorphism in C# and how is it achieved?
Answer:
Polymorphism allows objects of different types to be treated as objects of a common base type. In C#, polymorphism is achieved through:
Method Overriding (runtime polymorphism) – Using virtual and override keywords.
Method Overloading (compile-time polymorphism) – Defining multiple methods with the same name but different signatures.
38. What is the Observer design pattern and how is it implemented in C#?
Answer:
The Observer pattern is a behavioral design pattern where an object (subject) maintains a list of dependents (observers) and notifies them of state changes. It is commonly implemented using events and delegates in C#.
public class Subject
{
public event Action NotifyObservers;
public void ChangeState()
{
// State change logic
NotifyObservers?.Invoke();
}
}
39. What is the purpose of the dynamic keyword in C#?
Answer:
The dynamic keyword allows you to bypass compile-time type checking. The type of the object is determined at runtime, and all method and property calls on dynamic objects are resolved at runtime. This is useful for interoperability with COM objects, working with dynamic languages, or deserializing dynamic JSON.
40. What is the volatile keyword in C#?
Answer:
The volatile keyword is used to indicate that a field may be modified by multiple threads and prevents the compiler from applying certain optimizations that might lead to inconsistent results in multithreaded scenarios. It ensures that the value of the field is always read from and written to memory.
These additional C# .NET interview questions provide a comprehensive overview of advanced concepts in C#, focusing on practical usage, design patterns, and performance optimizations. They are designed to help experienced developers demonstrate their in-depth knowledge during interviews.
41. What is the difference between ref and out parameters in C#?
Answer:
ref: Requires that the variable be initialized before being passed into the method. The method can modify the value of the parameter, and the changes will be reflected outside the method.
out: Does not require the variable to be initialized before being passed into the method. The method must assign a value to the out parameter before it returns, and the changes will be reflected outside the method.
42. Explain the difference between Value Types and Reference Types in C#.
Answer:
Value Types: Stored on the stack, and each variable holds its own copy of the data. Modifications to one instance do not affect others (e.g., int, float, bool, struct).
Reference Types: Stored on the heap, and variables hold references to the memory location. Modifying one instance can affect all other references to the same object (e.g., class, string, array).
43. What is Deadlock in multithreading, and how can you prevent it in C#?
Answer:
A deadlock occurs when two or more threads are blocked forever, waiting for each other to release resources. It typically happens when multiple locks are involved. To prevent deadlocks:
Use consistent lock ordering (i.e., always acquire locks in the same order).
Use Monitor.TryEnter() with a timeout to avoid indefinite blocking.
Use fine-grained locking or lock-free data structures.
44. What is the difference between Equals() and == in C#?
Answer:
==: For value types, it compares the actual values. For reference types, it checks whether the two variables point to the same memory location (reference equality).
Equals(): Can be overridden to provide value-based equality for reference types. By default, it checks for reference equality, but for value types, it checks if the contents of the variables are the same.
45. What is Covariance and Contravariance in C#?
Answer:
Covariance: Allows you to assign a more derived type to a less derived type. It is supported for arrays, generic interfaces, and delegates.
IEnumerable<object> objects = new List<string>(); // Valid because of covariance.
Contravariance: Allows you to assign a less derived type to a more derived type. It is used with generic delegates and interfaces.
Action<string> actionString = (s) => Console.WriteLine(s);
Action<object> actionObject = actionString; // Valid due to contravariance.
46. What is lazy loading in C#?
Answer:
Lazy loading delays the initialization of an object until it is needed, improving application performance by avoiding unnecessary computation or resource allocation. In C#, lazy loading can be implemented using the Lazy<T> class.
Lazy<MyClass> myObject = new Lazy<MyClass>(() => new MyClass());
47. What are Attributes in C#, and how are they used?
Answer:
Attributes are used to add metadata to your code, such as marking methods or classes for special handling by the runtime or other tools. Attributes are enclosed in square brackets ([]) and can be applied to classes, methods, properties, and more. For example, [Obsolete] is an attribute that marks a method as deprecated.
[Obsolete("This method is deprecated.")]
public void OldMethod() { }
48. What is the ThreadPool in C#?
Answer:
The ThreadPool is a collection of worker threads managed by the .NET runtime. It allows efficient execution of short-lived, parallel tasks by reusing existing threads, thus reducing the overhead of creating and destroying threads. You can use ThreadPool.QueueUserWorkItem() to enqueue work items into the thread pool.
49. Explain the concept of Partial Classes in C#.
Answer:
Partial classes allow you to split the definition of a class across multiple files. This is useful when working with large classes or when auto-generated code is involved (such as in ASP.NET WebForms or Entity Framework). The partial keyword is used to declare that the class, method, or structure is spread across different files.
partial class MyClass
{
public void Method1() { }
}
partial class MyClass
{
public void Method2() { }
}
50. What is Task Parallel Library (TPL) in C#?
Answer:
Task Parallel Library (TPL) is a set of APIs that simplify parallel programming in .NET. TPL uses tasks (Task and Task<T>) to represent asynchronous operations and provides high-level constructs to perform parallel operations, such as Parallel.For, Parallel.ForEach, and Task.Run. It abstracts away the complexity of creating and managing threads.
51. What is the difference between Task.WaitAll and Task.WhenAll?
Answer:
Task.WaitAll: Blocks the current thread until all the provided tasks have completed. It is a synchronous operation and can cause thread starvation in some cases.
Task.WhenAll: Returns a task that completes when all the provided tasks have finished. It does not block the calling thread and is used in asynchronous programming with await.
52. What is the difference between Struct and Class in C#?
Answer:
Struct: Value type, stored on the stack, and passed by value. Structs are best suited for small, immutable data types (e.g., Point, DateTime).
Class: Reference type, stored on the heap, and passed by reference. Classes can have complex behaviors and are used for larger, mutable objects.
Structs do not support inheritance, while classes do.
53. What is a Tuple in C#, and when would you use it?
Answer:
A Tuple is a data structure that can hold a fixed number of elements of different types. Tuples are useful for returning multiple values from a method without needing to define a separate class.
var tuple = Tuple.Create(1, "Hello");
Console.WriteLine(tuple.Item1); // 1
Console.WriteLine(tuple.Item2); // Hello
54. What is Method Overriding and how is it different from Method Overloading?
Answer:
Method Overriding: Occurs when a derived class provides a specific implementation for a method that is already defined in its base class. The base method must be marked as virtual or abstract, and the derived class must use the override keyword.
Method Overloading: Involves defining multiple methods with the same name but different parameter lists (signatures) within the same class.
55. Explain Entity Framework Core and its advantages.
Answer:
Entity Framework Core (EF Core) is an open-source, lightweight, extensible, and cross-platform version of Entity Framework, an Object-Relational Mapper (ORM) for .NET. EF Core allows developers to interact with databases using C# code, without writing SQL queries. It supports LINQ queries, automatic change tracking, and migrations for database versioning. EF Core improves productivity, reduces boilerplate code, and is well-suited for modern web applications.
56. What is AOP (Aspect-Oriented Programming) and how can it be implemented in .NET?
Answer:
AOP (Aspect-Oriented Programming) is a programming paradigm that allows separation of cross-cutting concerns (like logging, security, and transactions) from the main business logic. In .NET, AOP can be implemented using libraries like PostSharp or Castle Windsor, or by manually writing interceptors and decorators. AOP reduces code duplication and improves modularity.
57. What are Events in C# and how do they work with delegates?
Answer:
Events in C# are built on top of delegates and provide a way for a class to notify other classes or objects when something happens. An event is a special type of delegate that only allows the subscribing methods to be called by the event publisher. Events are commonly used in GUI applications or for handling asynchronous programming.
public class Publisher
{
public event Action OnEventRaised;
public void RaiseEvent()
{
OnEventRaised?.Invoke();
}
}
58. What are Anonymous Methods and Lambda Expressions in C#?
Answer:
Anonymous Methods: Are inline, unnamed methods that are defined using the delegate keyword. They are used to write short pieces of code without having to create a separate method.
Lambda Expressions: Are a more concise way of writing anonymous methods. They are often used in LINQ queries or with delegates.
Func<int, int> square = x => x * x; // Lambda expression
59. What is the GC (Garbage Collector) in C#?
Answer:
The Garbage Collector (GC) is a part of the .NET runtime that automatically manages memory by reclaiming memory used by objects that are no longer needed. The GC uses a generational approach (Gen 0, Gen 1, Gen 2) to efficiently collect and free memory, reducing memory leaks and manual memory management efforts.
60. Explain Memory Leaks in .NET and how to avoid them.
Answer:
A memory leak occurs when objects are no longer used by the application but are not released by the GC, often because they are still referenced somewhere in the code. To avoid memory leaks:
Use weak references where appropriate.
Unsubscribe from events when they are no longer needed.
Properly implement the IDisposable pattern to free unmanaged resources.
Avoid static references that hold large objects.
No comments:
Post a Comment