public static class StringExtensions {
public static bool IsNullOrEmpty(this string? value) => string.IsNullOrEmpty(value);
}
string? name = null;
bool empty = name.IsNullOrEmpty(); // called as if it were an instance method
Topics
32
Arrays, Span<T> & Memory<T>
Asynchronous Programming
Attributes & Reflection
Collections
Delegates, Events & Lambdas
Dependency Injection & IoC Principles
Design Patterns in C#
Enums & Flags
Equality: Equals, GetHashCode & IEquatable
Exception Handling
Extension Methods
File I/O & Streams
Fundamentals
Generics
Indexers & Operator Overloading
Interfaces & Abstract Classes
Iterators & yield return
LINQ
Memory & Garbage Collection
Modern C# Features (Global Usings, File-Scoped Namespaces, Top-Level Statements)
Multithreading & Task Parallel Library
Nullable Reference Types
Nullable Value Types (Nullable<T>)
OOP
Records & Pattern Matching
Regular Expressions in C#
Serialization (System.Text.Json)
String Handling & StringBuilder
Structs, Boxing & Unboxing
Tuples & Deconstruction
Unit Testing (xUnit/NUnit/MSTest)
Value vs Reference Types
Extension Methods
11 questions found
An extension method lets you 'add' new methods to an existing type (even one you don't own the source for, like a built-in .NET type) without modifying it — declared as a static method in a static class, with the FIRST parameter prefixed with 'this', specifying which type it extends.
Real-world example
Adding a convenient .IsValidEmail() check directly onto the built-in 'string' type without subclassing or wrapping it.
Fundamentals
Why must extension methods be defined in a static class, and how does the compiler resolve a call to one?
BeginnerExtension methods are purely a COMPILE-TIME convenience — the compiler resolves 'obj.ExtensionMethod()' by rewriting it internally as 'StaticClass.ExtensionMethod(obj)', which requires the method to live in a static class; at runtime, there's no real difference from calling an ordinary static method.
public static class IntExtensions {
public static bool IsEven(this int number) => number % 2 == 0;
}
int x = 4;
bool even = x.IsEven(); // syntactic sugar for:
bool even2 = IntExtensions.IsEven(x); // this equivalent static call
Real-world example
Understanding that extension methods don't actually modify the extended type at all — they're purely compiler-level syntactic sugar.
Fundamentals
How does method resolution priority work when an extension method has the SAME name and signature as an actual instance method on the type?
IntermediateA genuine INSTANCE method on the type ALWAYS takes priority over an extension method with a matching signature — the compiler only falls back to searching for an applicable extension method if no instance method (or property/field) matches, meaning you can never accidentally 'override' real instance method behavior with an extension method.
public class Calculator {
public int Add(int a, int b) => a + b; // real instance method
}
public static class CalculatorExtensions {
public static int Add(this Calculator calc, int a, int b) => 999; // never actually called
}
new Calculator().Add(2, 3); // always calls the instance method, returns 5
Real-world example
Understanding why adding an extension method with the same name as an existing instance method silently has no effect on calls to that instance method.
Fundamentals
How do you write a generic extension method that works with any collection type, like a custom 'IsEmpty()' check?
IntermediateAdd a generic type parameter to the extension method itself (after the static method's name), constrained as needed, and use it in the 'this' parameter's type — this lets a single extension method work across many different concrete generic instantiations.
public static class EnumerableExtensions {
public static bool IsEmpty<T>(this IEnumerable<T> source) => !source.Any();
}
List<int> numbers = new();
bool empty = numbers.IsEmpty(); // true, works for any IEnumerable<T>
Real-world example
Adding a convenient .IsEmpty() or .None() check reusable across List<T>, arrays, and any other IEnumerable<T> implementation.
Generics
How do you chain multiple extension methods together in a fluent style, and what design principle makes this possible?
IntermediateAs long as each extension method RETURNS a value of a type that has further applicable extension (or instance) methods, calls can be chained one after another — this is exactly the mechanism that makes LINQ's fluent query syntax (.Where().Select().OrderBy()) work.
public static class StringExtensions {
public static string Trimmed(this string s) => s.Trim();
public static string Capitalized(this string s) => char.ToUpper(s[0]) + s[1..];
}
string result = " hello world ".Trimmed().Capitalized(); // "Hello world"
Real-world example
Building a fluent, chainable string-processing or validation API similar in style to LINQ's own method chaining.
LINQ
How would you write an extension method on an interface (like IEnumerable<T>) that provides a default implementation shared across EVERY concrete implementing type?
AdvancedExtension methods on an interface type automatically become available to ALL classes/structs implementing that interface, without those types needing any changes — this is precisely how virtually all of LINQ works, adding dozens of query methods to every IEnumerable<T> implementation across the entire .NET ecosystem, including your own custom collections.
public static class MyLinqExtensions {
public static T? SecondOrDefault<T>(this IEnumerable<T> source) {
using var enumerator = source.GetEnumerator();
if (enumerator.MoveNext() && enumerator.MoveNext()) return enumerator.Current;
return default;
}
}
var list = new List<int> { 1, 2, 3 };
int second = list.SecondOrDefault(); // 2 -- works automatically, since List<T> implements IEnumerable<T>
Real-world example
Adding a custom LINQ-style query method that automatically works across every existing and future IEnumerable<T> implementation.
Interfaces & Abstract Classes
How would you write extension methods to build a lightweight, fluent validation/guard-clause library?
AdvancedChain extension methods on a generic wrapper (or directly on the value type being validated) where each validation method either RETURNS the original value (for chaining) or THROWS if the condition fails — producing concise, self-documenting validation code without a heavy external dependency.
public static class GuardExtensions {
public static T NotNull<T>(this T value, string paramName) where T : class =>
value ?? throw new ArgumentNullException(paramName);
public static int Positive(this int value, string paramName) =>
value > 0 ? value : throw new ArgumentOutOfRangeException(paramName, "Must be positive");
}
public Order(Customer customer, int quantity) {
Customer = customer.NotNull(nameof(customer));
Quantity = quantity.Positive(nameof(quantity));
}
Real-world example
Building a lightweight, dependency-free set of reusable guard-clause validators for constructor and method argument checking.
Exception Handling
Why can't extension methods be used to add STATIC members, operators, or FIELDS to an existing type, and what are the practical implications of this limitation?
AdvancedExtension methods only extend the set of callable INSTANCE methods available on a type through syntactic sugar — they can't add actual state (fields), can't participate in operator overloading, and can't extend static method call syntax on the type itself, because none of these actually modify the type's real metadata; the extended type genuinely gains nothing at the runtime/reflection level.
public static class StringExtensions {
// public static string EmptyValue = ""; // Error: can't add a static field this way
// public static string operator +(string a, string b) => a + b; // Error: extension methods can't define operators
}
Real-world example
Understanding why you must use inheritance, composition, or a wrapper type instead of extension methods when you genuinely need to add state to a type.
OOP
How do 'extension method ambiguity' conflicts arise when two different NuGet packages or namespaces define extension methods with the identical signature, and how do you resolve them?
AdvancedIf two 'using' namespaces are both in scope and both define an applicable extension method with an identical signature for the same type, the compiler reports an AMBIGUOUS CALL error — resolved either by removing one of the conflicting 'using' directives, or by explicitly calling the desired method using its full static syntax (ClassName.Method(instance, ...)) to disambiguate.
// Both LibraryA.Extensions and LibraryB.Extensions define: string Truncate(this string s, int length)
using LibraryA.Extensions;
using LibraryB.Extensions;
string result = "hello".Truncate(3); // Error: ambiguous call between the two
// Fix: LibraryA.Extensions.StringExtensions.Truncate("hello", 3); // explicit disambiguation
Real-world example
Resolving a real compile error after adding a second NuGet package that happens to define a conflicting extension method name.
Fundamentals
How would you write generic extension methods leveraging C# 11's generic math interfaces (like INumber<T>) to build a single reusable numeric utility working across int, double, decimal, and other numeric types?
AdvancedConstrain the extension method's generic type parameter to INumber<T> (or a more specific numeric interface like IFloatingPoint<T>), letting you write ONE generic implementation using standard arithmetic operators that works correctly and efficiently across every built-in (and custom) numeric type implementing that interface, without needing separate overloads for each numeric type.
public static class NumericExtensions {
public static T Clamp<T>(this T value, T min, T max) where T : INumber<T> =>
value < min ? min : (value > max ? max : value);
}
int clampedInt = 15.Clamp(0, 10); // 10
double clampedDouble = 2.5.Clamp(0.0, 5.0); // 2.5
Real-world example
Writing a single generic Clamp(), Sum(), or Average() utility that works identically across int, double, decimal, and float without duplicated overloads.
Generics
Showing 1–10 of 11