TheDocumentation Index
Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt
Use this file to discover all available pages before exploring further.
[] (element access) operator provides indexed access to elements within arrays, spans, pointers, and custom types that implement indexers. It evaluates a base expression and one or more index expressions to return a reference or value associated with a specific logical position, physical memory offset, or mapped key.
Underlying Mechanics
The behavior and compilation of the[] operator depend entirely on the type of the base expression it is applied to.
1. Arrays (T[], T[,])
For built-in arrays, the CLR handles the [] operator intrinsically, but the emitted Intermediate Language (IL) differs based on the array’s rank:
- Single-dimensional arrays (
T[]): The compiler generatesldelemandstelemIL instructions that calculate the direct memory offset from the array’s base address. - Multi-dimensional arrays (
T[,]): The compiler emitscallinstructions to the multi-dimensional array’s intrinsicGetandSetmethods rather than using direct element-loading instructions. - Bounds Checking: The CLR automatically injects bounds-checking instructions before memory access. If the index falls outside the allocated memory range, the runtime throws an
IndexOutOfRangeException.
2. Custom Types (Indexers)
When applied to a class, struct, or interface, the[] operator is syntactic sugar for invoking an indexer. Indexers are not restricted to zero-based integers; they can accept any type as an argument (e.g., string in a dictionary).
- MSIL Translation: The compiler translates the
[]syntax into calls to underlying methods, typically namedget_Itemandset_Item. - Overloading: While the
[]operator cannot be overloaded directly via theoperatorkeyword, types can define multiple indexers with different signatures (e.g.,this[int i],this[string key]). - Attribute Override: The default
Itemname in the emitted IL can be modified using the[IndexerName("NewName")]attribute.
3. Null-Conditional Element Access (?[])
The ?[] operator provides null-safe element access. If the base expression evaluates to null, the operator short-circuits and avoids invoking the indexer or array access, which prevents a NullReferenceException. As a consequence of this short-circuiting, the index expressions inside the brackets are not evaluated, preventing any unintended side-effects from those expressions.
Crucially, the ?[] operator performs type lifting. If the underlying array or indexer returns a non-nullable value type (e.g., int), using the ?[] operator changes the expression’s compile-time return type to Nullable<T> (e.g., int?). Because of this type lifting, attempting to assign the result directly to a non-nullable value type (e.g., int item = collection?[0];) will result in a compiler error.
4. Index Initializers
During object initialization, the[] operator functions as an index initializer. Expressions utilizing this syntax (e.g., new Dictionary<string, int> { ["key"] = 1 }) are translated by the compiler into an object instantiation followed by direct calls to the type’s set_Item indexer method for each specified key.
5. Pointers (Unsafe Context)
In anunsafe context, applying the [] operator to a pointer (T*) performs raw pointer arithmetic.
- Equivalence: The expression
p[i]is strictly evaluated as*(p + i). - Memory Safety: Unlike arrays, pointer element access bypasses all CLR bounds checking. The developer is responsible for ensuring the calculated memory address is valid.
Modern C# Integration (System.Index and System.Range)
The [] operator natively supports System.Index and System.Range types, altering its mechanical evaluation:
- Index (
^operator): When passed anIndex(e.g.,collection[^1]), the compiler translates this into an offset from the end of the collection. For arrays,collection[^i]is compiled ascollection[collection.Length - i]. - Range (
..operator): When passed aRange(e.g.,collection[1..4]), the[]operator does not return a single element. Instead, it returns a slice.- For arrays, this allocates and returns a new array.
- For
Span<T>or types implementing aSlice(int start, int length)method, it returns a non-allocating view of the memory.
Evaluation Order
When the[] operator is invoked, the expressions are evaluated strictly from left to right. The base collection expression is evaluated first, followed by the index expressions in the exact order they appear within the brackets.
Master C# with Deep Grasping Methodology!Learn More





