← Back to Articles         
Modern C# Features – Part 2

Modern C# Features – Part 2

Published on 12 Oct 2026     7 min read C#
Modern C# Features

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 using makes 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 using statements.

  • Can be placed in a dedicated GlobalUsings.cs file.

  • 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 as Employee.

  • List<string> names = new(); creates a List<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.Id accesses the first value.

  • var (id, name) extracts both values into separate variables.

Key Points

  • Modern tuple syntax was introduced in C# 7.

  • Uses ValueTuple internally.

  • 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 inside Calculate().

  • 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:

  • Point is a record struct with automatically generated value equality.

  • p1 == p2 returns true because their values match.

  • Amount is a readonly struct.

  • Value cannot be reassigned after construction.

Comparison

Feature

record struct

readonly struct

Type

Value type

Value type

Value equality

Generated automatically

Requires custom implementation for ==

Immutability

Mutable by default

Restricts instance mutation

Generated ToString()

Yes

No special generated formatting

Primary use

Small data models

Immutable value types

Key Points

  • Both are value types.

  • record struct was introduced in C# 10.

  • readonly struct was introduced in C# 7.2.

  • readonly record struct combines 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:

  • T is 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.

  • IntCalculator must 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 new

C# 9

Simplify object creation

Tuples & Deconstruction

C# 7

Group and extract multiple values

Local Functions

C# 7

Declare helper methods inside methods

record struct

C# 10

Value types with generated value equality

readonly struct

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.

← Back to Articles