int[] numbers = new int[5];
int[] scores = { 90, 85, 78 };
string[] names = new string[] { "Sam", "Alex" };
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
Arrays, Span<T> & Memory<T>
11 questions found
Arrays in C# have a fixed size set at creation time, declared with square brackets after the element type, and can be initialized with a collection expression or explicit 'new' syntax.
Real-world example
Storing a fixed set of monthly sales figures where the count (12 months) never changes.
Collections
How do you create and work with a multidimensional (rectangular) array versus a jagged array?
BeginnerA rectangular array (int[,]) has a fixed grid shape where every row has the same length; a jagged array (int[][]) is an array of arrays, where each inner array can have a different length, offering more flexibility at the cost of an extra indirection.
int[,] grid = new int[3, 3]; // rectangular: fixed 3x3
grid[0, 0] = 1;
int[][] jagged = new int[3][];
jagged[0] = new int[] { 1, 2 };
jagged[1] = new int[] { 1, 2, 3 };
Real-world example
Using a rectangular array for a fixed game board, versus a jagged array for storing rows of variable-length CSV data.
Fundamentals
Span<T> is a stack-only (ref struct) type representing a contiguous, type-safe view over a region of memory — it lets you slice arrays, strings, or stack-allocated memory WITHOUT copying data, avoiding the allocation overhead of creating new sub-arrays or substrings for temporary operations.
int[] source = { 1, 2, 3, 4, 5 };
Span<int> slice = source.AsSpan(1, 3); // view over elements [2, 3, 4], no copy
slice[0] = 99; // mutates the original array too, since it's a view
Real-world example
Parsing a large string or byte buffer in-place (e.g., a CSV line) without allocating a new substring for every field.
Memory & Garbage Collection
Memory<T> is a heap-allocatable counterpart to Span<T> — since Span<T> is a ref struct restricted to the stack (can't be used in async methods, lambdas capturing it, or as a class field), Memory<T> can be stored anywhere and converted to a Span<T> (via .Span) only when you actually need to access the underlying data synchronously.
async Task ProcessAsync(Memory<byte> buffer) {
await Task.Delay(10); // Span<T> couldn't survive this await, but Memory<T> can
Span<byte> span = buffer.Span; // convert to Span<T> only when actually processing
span[0] = 0xFF;
}
Real-world example
Passing a buffer through an async I/O pipeline (like a network stream reader) where Span<T> couldn't cross an 'await' boundary.
Asynchronous Programming
How do you slice an array or string efficiently without allocating a new array/string, using Span<T> or ReadOnlySpan<T>?
IntermediateCall .AsSpan() (with optional start/length arguments) on an array or string to get a Span<T> or ReadOnlySpan<char> view over just that portion — no new memory is allocated, unlike Substring() or array slicing with LINQ's Skip/Take, which both copy data.
string text = "Hello, World!";
ReadOnlySpan<char> hello = text.AsSpan(0, 5); // 'Hello', no allocation
int[] arr = { 1, 2, 3, 4, 5 };
Span<int> middle = arr.AsSpan(1, 3); // [2, 3, 4], no allocation
Real-world example
Parsing a large log file line-by-line, slicing out fields without allocating a new string for every single token.
String Handling & StringBuilder
Because Span<T> can point directly at stack memory, the compiler restricts it to prevent that memory from outliving its valid scope: it cannot be boxed, cannot be a field of a non-ref-struct class, cannot be used in async methods or iterators (yield return), and cannot be captured by a lambda or local function that might outlive the current stack frame.
// class Container { Span<int> data; } // Error: cannot use Span<T> as a field in a regular class
async Task Bad() {
Span<int> span = stackalloc int[10];
await Task.Delay(1); // Error: cannot use Span<T> across an await
}
Real-world example
Understanding why a Span<T>-based helper method can't be trivially converted into an async method or a yield-based iterator.
Iterators & yield return
How does 'stackalloc' work together with Span<T> to allocate memory on the stack instead of the heap?
Advanced'stackalloc' allocates a block of memory directly on the CURRENT STACK FRAME (not the garbage-collected heap), and assigning it to a Span<T> gives you safe, bounds-checked access to that memory — ideal for small, short-lived buffers in performance-critical code, completely avoiding GC pressure, but the memory is only valid for the lifetime of the current method call.
Span<int> buffer = stackalloc int[100]; // allocated on the stack, zero GC pressure
for (int i = 0; i < buffer.Length; i++) {
buffer[i] = i * i;
}
Real-world example
Building a small, fixed-size scratch buffer for a hot-path numeric algorithm, avoiding heap allocation entirely.
Memory & Garbage Collection
How would you write a high-performance CSV field parser using ReadOnlySpan<char> that avoids all intermediate string allocations?
AdvancedUse ReadOnlySpan<char>.IndexOf() or Split-style enumeration to locate delimiters directly within the original string's span, slicing out each field as its own ReadOnlySpan<char> — only convert a field to an actual 'string' (via .ToString()) at the very last moment when you genuinely need to store or return it as a heap-allocated string.
ReadOnlySpan<char> line = "Sam,30,Engineer".AsSpan();
int firstComma = line.IndexOf(',');
ReadOnlySpan<char> name = line.Slice(0, firstComma); // no allocation yet
ReadOnlySpan<char> rest = line.Slice(firstComma + 1);
// ... continue slicing 'rest' for remaining fields
Real-world example
Parsing millions of lines of a large CSV or log file in a batch job where allocation overhead directly impacts throughput.
String Handling & StringBuilder
How does the modern .NET Span-based string.Split (via MemoryExtensions) or manual span-splitting reduce garbage collection pressure compared to string.Split()?
AdvancedRegular string.Split() allocates a new string array AND a new string object for EVERY resulting substring; span-based splitting techniques (like a manual span-walking loop, or newer .NET SpanSplitEnumerator APIs) can iterate over each segment as a ReadOnlySpan<char> without allocating anything for segments you only need to read or compare, not store.
ReadOnlySpan<char> csv = "a,b,c,d,e".AsSpan();
foreach (var segment in csv.Split(',')) { // conceptual, using newer span-splitting APIs
// process each segment as a span, zero string allocations
}
// vs. "a,b,c,d,e".Split(',') -- allocates a string[] AND 5 string objects
Real-world example
Reducing GC pauses in a high-throughput data ingestion pipeline processing millions of delimited records per second.
Memory & Garbage Collection
How would you use Span<T> to implement an in-place array reversal or sorting algorithm without allocating a temporary array?
AdvancedSpan<T> supports the same indexed read/write access as a regular array with none of the allocation overhead of copying — algorithms like in-place reversal or a custom sort can operate directly on a Span<T> (or a slice of one), swapping elements by index exactly as you would on a raw array, but with the added flexibility of it being a VIEW that could point into a larger buffer.
void ReverseInPlace(Span<int> span) {
int left = 0, right = span.Length - 1;
while (left < right) {
(span[left], span[right]) = (span[right], span[left]);
left++; right--;
}
}
int[] arr = { 1, 2, 3, 4, 5 };
ReverseInPlace(arr.AsSpan()); // arr is now { 5, 4, 3, 2, 1 }, zero extra allocation
Real-world example
Implementing performance-critical, allocation-free array manipulation utilities in a numeric or data-processing library.
Iterators & yield return
Showing 1–10 of 11