Modern C# Features – Part 2 (Interview Questions)
1. What Are File-Scoped Namespaces?
File-scoped namespaces (C# 10) allow declaring a namespace without curly braces {}.
They reduce indentation and make code cleaner.
Example
Traditional Namespace:
namespace MyApplication
{
public class Employee
{
public string Name { get; set; } = "";
}
}
File-Scoped Namespace:
namespace MyApplication;
public class Employee
{
public string Name { get; set; } = "";
}
Explanation:
-
namespace MyApplication;applies to the entire file. -
No curly braces are required.
-
Both approaches provide the same namespace functionality.
Key Points
-
Introduced in C# 10.
-
Reduces indentation and boilerplate code.
-
Only one file-scoped namespace declaration is allowed per file.
-
Commonly used in ASP.NET Core projects.
2. What Are Global Using Directives?
Global using directives (C# 10) allow importing namespaces once and making them available across all C# files in the project.
Example
GlobalUsings.cs
global using System;
global using System.Collections.Generic;
global using System.Linq;
EmployeeService.cs
public class EmployeeService
{
public List<string> GetNames()
{
return new List<string> { "John", "David" };
}
}
Explanation:
-
global usingmakes namespaces available throughout the project. -
No need to repeat
using System.Collections.Generic;in every file. -
Helps reduce repetitive code.
Key Points
-
Introduced in C# 10.
-
Applies across the current project/compilation.
-
Reduces duplicate
usingstatements. -
Can be placed in a dedicated
GlobalUsings.csfile. -
ASP.NET Core projects may enable implicit global usings automatically.
3. What Are Target-Typed new Expressions?
Target-typed new expressions (C# 9) allow creating objects without repeating the type name when the compiler can determine it from the context.
Example
public class Employee
{
public string Name { get; set; } = "";
}
// Traditional
Employee emp1 = new Employee();
// Target-typed new
Employee emp2 = new();
List<string> names = new();
Explanation:
-
Employee emp2 = new();automatically identifies the type asEmployee. -
List<string> names = new();creates aList<string>. -
Reduces repetitive type declarations.
Key Points
-
Introduced in C# 9.
-
Improves code readability.
-
Requires a known target type.
-
Cannot use
var emp = new();because the compiler cannot infer the type.
4. What Are Tuples and Deconstruction?
A tuple allows returning or storing multiple values together without creating a separate class.
Deconstruction extracts tuple values into individual variables.
Example
static (int Id, string Name) GetEmployee()
{
return (101, "John");
}
// Tuple
var employee = GetEmployee();
Console.WriteLine(employee.Id);
Console.WriteLine(employee.Name);
// Deconstruction
var (id, name) = GetEmployee();
Console.WriteLine($"{id} - {name}");
Output:
101
John
101 - John
Explanation:
-
(int Id, string Name)defines a tuple. -
The method returns two values.
-
employee.Idaccesses the first value. -
var (id, name)extracts both values into separate variables.
Key Points
-
Modern tuple syntax was introduced in C# 7.
-
Uses
ValueTupleinternally. -
Supports returning multiple values from methods.
-
Deconstruction improves readability.
-
For complex business data, DTOs or records are usually preferable.
5. What Are Local Functions?
Local functions (C# 7) are methods declared inside another method.
They are useful when a helper function is needed only within a particular method.
Example
public static void Calculate()
{
int result = Add(10, 20);
Console.WriteLine(result);
int Add(int a, int b)
{
return a + b;
}
}
Calculate();
Output:
30
Explanation:
-
Add()is declared insideCalculate(). -
It can be called only within its containing scope.
-
It keeps helper logic close to where it is used.
Key Points
-
Introduced in C# 7.
-
Can access variables from the enclosing method.
-
Supports recursion.
-
Can be asynchronous.
-
Useful for small helper methods and validation logic.
6. What Are record struct and readonly struct?
Both are value types, but they serve different purposes.
record struct (C# 10) provides value-based equality and automatically generated members.
readonly struct (C# 7.2) prevents instance fields from being reassigned after construction and helps enforce immutability.
Example
public record struct Point(int X, int Y);
public readonly struct Amount
{
public int Value { get; }
public Amount(int value)
{
Value = value;
}
}
// Usage
Point p1 = new(10, 20);
Point p2 = new(10, 20);
Console.WriteLine(p1 == p2);
Amount amount = new(500);
Console.WriteLine(amount.Value);
Output:
True
500
Explanation:
-
Pointis a record struct with automatically generated value equality. -
p1 == p2returnstruebecause their values match. -
Amountis a readonly struct. -
Valuecannot be reassigned after construction.
Comparison
|
Feature |
|
|
|---|---|---|
|
Type |
Value type |
Value type |
|
Value equality |
Generated automatically |
Requires custom implementation for |
|
Immutability |
Mutable by default |
Restricts instance mutation |
|
Generated |
Yes |
No special generated formatting |
|
Primary use |
Small data models |
Immutable value types |
Key Points
-
Both are value types.
-
record structwas introduced in C# 10. -
readonly structwas introduced in C# 7.2. -
readonly record structcombines record features with readonly semantics. -
Readonly does not guarantee deep immutability of referenced objects.
7. What Are Raw String Literals?
Raw string literals (C# 11) allow writing strings containing quotes, backslashes, and multiple lines without normal escape sequences.
They are useful for JSON, SQL, XML, and HTML.
Example
Traditional String:
string json = "{\"name\":\"John\",\"age\":30}";
Raw String Literal:
string json = """
{
"name": "John",
"age": 30
}
""";
Console.WriteLine(json);
Output:
{
"name": "John",
"age": 30
}
Explanation:
-
Triple double quotes
"""define a raw string literal. -
Double quotes inside the string do not need escaping.
-
Multiline text can be written naturally.
Key Points
-
Introduced in C# 11.
-
Reduces escape characters.
-
Useful for JSON, SQL, HTML, and XML.
-
Supports multiline strings.
-
Supports interpolation using
$with the appropriate brace syntax.
8. What Are Generic Math and Static Abstract Interface Members?
Generic math (C# 11) allows writing mathematical operations that work with different numeric types using generic constraints.
Static abstract interface members allow interfaces to require implementing types to provide static members, including operators.
Example
using System.Numerics;
public static T Add<T>(T a, T b)
where T : INumber<T>
{
return a + b;
}
// Usage
Console.WriteLine(Add(10, 20));
Console.WriteLine(Add(10.5, 20.5));
Output:
30
31
Explanation:
-
Tis a generic numeric type. -
INumber<T>provides a common numeric contract. -
The
+operator is available through the interface constraint. -
The same method works with
int,double,decimal, and other compatible numeric types.
How It Works
Add<T>(a, b)
|
INumber<T>
|
+--------+--------+
| | |
int double decimal
| | |
Add Add Add
Static Abstract Interface Example
public interface ICalculator<T>
{
static abstract T Add(T a, T b);
}
public class IntCalculator : ICalculator<int>
{
public static int Add(int a, int b)
{
return a + b;
}
}
Explanation:
-
The interface declares a static abstract method.
-
IntCalculatormust implement the method. -
This enables generic code to invoke static operations through appropriate type constraints.
Key Points
-
Introduced in C# 11.
-
Generic math uses interfaces such as
INumber<T>. -
Supports reusable mathematical algorithms.
-
Static abstract members can define operators and other static contracts.
-
Useful in mathematical libraries, financial calculations, and generic algorithms.
Quick Interview Revision
|
Feature |
C# Version |
Main Purpose |
|---|---|---|
|
File-Scoped Namespace |
C# 10 |
Reduce namespace indentation |
|
Global Using |
C# 10 |
Share namespace imports across files |
|
Target-Typed |
C# 9 |
Simplify object creation |
|
Tuples & Deconstruction |
C# 7 |
Group and extract multiple values |
|
Local Functions |
C# 7 |
Declare helper methods inside methods |
|
|
C# 10 |
Value types with generated value equality |
|
|
C# 7.2 |
Restrict mutation of value types |
|
Raw String Literals |
C# 11 |
Simplify multiline and escaped text |
|
Generic Math |
C# 11 |
Perform numeric operations generically |
|
Static Abstract Interface Members |
C# 11 |
Define static contracts in interfaces |
Interview Priority: Focus first on file-scoped namespaces, global using, target-typed new, tuples, record structs, and primary constructors. Generic math and static abstract interface members are more advanced topics.