C# Methods and Resource Management
1. What are expression-bodied members?
Definition: Expression-bodied members allow you to write simple methods, properties, and constructors using the => operator instead of a traditional method body.
They make code shorter and more readable.
Example
public class Calculator
{
// Normal method
public int Add(int a, int b)
{
return a + b;
}
// Expression-bodied method
public int Multiply(int a, int b) => a * b;
}
Usage:
Calculator calc = new Calculator();
Console.WriteLine(calc.Add(10, 20)); // 30
Console.WriteLine(calc.Multiply(10, 20)); // 200
Explanation
-
Add()uses the traditional method body withreturn. -
Multiply()uses=>to return the result directly. -
Both approaches provide the same functionality.
Expression-bodied members also work with properties:
public string Name => "John";
Key Points
-
=>is called the expression-body operator in this context. -
Reduces boilerplate code.
-
Supports methods, properties, constructors, indexers, and other members.
-
Best suited for simple, single-expression operations.
-
Complex business logic is generally easier to maintain with traditional method bodies.
2. What are optional and named parameters?
Definition: Optional parameters allow you to omit arguments when calling a method. Named parameters allow you to pass arguments by their parameter names instead of relying only on their positions.
Example
public class Employee
{
public void Display(
string name,
string department = "IT",
int age = 25)
{
Console.WriteLine(
$"{name} - {department} - {age}");
}
}
Usage:
Employee emp = new Employee();
// Optional parameters
emp.Display("John");
// All parameters
emp.Display("David", "HR", 30);
// Named parameters
emp.Display(name: "Peter", age: 35);
Output:
John - IT - 25
David - HR - 30
Peter - IT - 35
Explanation
Optional parameters:
emp.Display("John");
Only the required name argument is provided. The compiler uses the default values for department and age.
Named parameters:
emp.Display(name: "Peter", age: 35);
-
namereceives"Peter". -
agereceives35. -
departmentuses its default value"IT".
Key Points
-
Optional parameters must come after required parameters.
-
Optional parameters require compile-time constant defaults (with certain supported exceptions such as
default). -
Named parameters improve readability.
-
Named parameters allow you to skip optional parameters.
-
Both features help reduce unnecessary method overloads.
3. What are extension methods, and when should they be used?
Definition: Extension methods allow you to add new methods to existing types without modifying their source code or inheriting from them.
Extension methods are commonly used in LINQ and reusable helper functionality.
Example
Suppose you want to add a method to the string type that converts text to uppercase.
public static class StringExtensions
{
public static string ToUpperText(this string value)
{
return value.ToUpper();
}
}
Usage:
string name = "john";
string result = name.ToUpperText();
Console.WriteLine(result);
Output:
JOHN
Explanation
-
StringExtensionsis a static class. -
ToUpperText()is a static method. -
this string valuespecifies that the method extendsstring. -
You can call
ToUpperText()as though it were an instance method ofstring.
Flow Diagram
string name = "john"
|
v
name.ToUpperText()
|
v
StringExtensions.ToUpperText(name)
|
v
value.ToUpper()
|
v
"JOHN"
When should extension methods be used?
-
To add reusable helper methods to existing types.
-
To extend framework or third-party types without modifying them.
-
To create fluent APIs and readable method chains.
-
To implement custom LINQ-style operations.
Key Points
-
Extension methods must be declared in a non-generic static class.
-
Extension methods themselves must be static.
-
The first parameter uses the
thiskeyword. -
The namespace containing the extension method must be in scope.
-
Extension methods do not actually modify the original type.
-
Applicable instance methods take precedence over extension methods.
Real-world example: LINQ methods such as Where(), Select(), and OrderBy() are extension methods.
4. What is the difference between a finalizer and Dispose()?
Definition: Both are associated with resource cleanup, but they work differently.
-
Finalizer: Provides cleanup when the Garbage Collector determines that an object is eligible for finalization.
-
Dispose(): Allows resources to be released explicitly and deterministically.
Example
public class FileManager : IDisposable
{
public void Dispose()
{
Console.WriteLine("Dispose called");
GC.SuppressFinalize(this);
}
~FileManager()
{
Console.WriteLine("Finalizer called");
}
}
Usage:
using (FileManager file = new FileManager())
{
Console.WriteLine("Working with file");
}
Output:
Working with file
Dispose called
Explanation
-
A
FileManagerobject is created. -
The application executes the code inside the
usingblock. -
When execution leaves the block,
Dispose()is called automatically. -
GC.SuppressFinalize(this)prevents the finalizer from running for that object.
Note: This is a demonstration of the cleanup lifecycle. A real implementation should release its owned resources inside Dispose(). Finalizers are generally needed only when a class directly owns unmanaged resources.
Flow Diagram
Object Created
|
+-------+-------+
| |
v v
using / Dispose No explicit Dispose
| |
v v
Dispose() called Object becomes
| unreachable
v |
Release resources v
| Garbage Collector
v |
Suppress finalizer v
Finalizer may run
later
Differences
|
Feature |
Finalizer |
Dispose() |
|---|---|---|
|
Execution |
Managed by GC finalization |
Explicit or |
|
Timing |
Unpredictable |
Deterministic |
|
Interface |
Not required |
Usually |
|
Performance |
Adds GC overhead |
Generally more efficient |
|
Purpose |
Fallback for unmanaged cleanup |
Timely resource cleanup |
|
Syntax |
|
|
Key Points
-
Dispose()is the preferred way to release resources promptly. -
Finalizers run at an unpredictable time and are not guaranteed to run at process shutdown.
-
usingautomatically callsDispose(), even if an exception occurs inside the block. -
IDisposabledefines theDispose()contract. -
GC.SuppressFinalize(this)avoids unnecessary finalization when applicable. -
For asynchronous cleanup, C# also supports
IAsyncDisposableandawait using.
Quick Interview Revision
|
Concept |
Remember |
|---|---|
|
Expression-bodied members |
Use |
|
Optional parameters |
Provide default argument values |
|
Named parameters |
Pass arguments using parameter names |
|
Extension methods |
Add callable methods to existing types using |
|
Finalizer |
GC-managed, nondeterministic cleanup |
|
Dispose() |
Explicit, deterministic resource cleanup |
Important interview takeaway: Expression-bodied members, optional parameters, named parameters, and extension methods primarily improve code readability and reusability. Dispose() and finalizers concern resource lifetime and cleanup.