Skip to content

Clarify index and range usages #46496

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "Member access and null-conditional operators and expressions:"
description: "C# operators that you use to access type members or null-conditionally access type members. These operators include the dot operator - `.`, indexers - `[`, `]`, `^` and `..`, and invocation - `(`, `)`."
ms.date: 04/04/2025
ms.date: 05/29/2025
author: pkulikov
f1_keywords:
- "._CSharpKeyword"
Expand Down Expand Up @@ -35,7 +35,7 @@ helpviewer_keywords:
---
# Member access operators and expressions - the dot, indexer, and invocation operators.

You use several operators and expressions to access a type member. Member access operators include member access (`.`), array element, or indexer access (`[]`), index-from-end (`^`), range (`..`), null-conditional operators (`?.` and `?[]`), and method invocation (`()`). These include the *null-conditional* member access (`?.`), and indexer access (`?[]`) operators.
You use several operators and expressions to access a type member. Member access operators include member access (`.`), array element, or indexer access (`[]`), index-from-end (`^`), range (`..`), null-conditional operators (`?.` and `?[]`), and method invocation (`()`). These operators include the *null-conditional* member access (`?.`), and indexer access (`?[]`) operators.

- [`.` (member access)](#member-access-expression-): to access a member of a namespace or a type
- [`[]` (array element or indexer access)](#indexer-operator-): to access an array element or a type indexer
Expand Down Expand Up @@ -205,6 +205,9 @@ You also use parentheses to adjust the order in which to evaluate operations in

Index and range operators can be used with a type that is *countable*. A *countable* type is a type that has an `int` property named either `Count` or `Length` with an accessible `get` accessor. [Collection expressions](./collection-expressions.md) also rely on *countable* types.

> [!NOTE]
> Single dimensional arrays are *countable*. Multi-dimensional arrays aren't. The `^` and `..` (range) operators can't be used in multi-dimensional arrays.

The `^` operator indicates the element position from the end of a sequence. For a sequence of length `length`, `^n` points to the element with offset `length - n` from the start of a sequence. For example, `^1` points to the last element of a sequence and `^length` points to the first element of a sequence.

:::code language="csharp" source="snippets/shared/MemberAccessOperators.cs" id="IndexFromEnd":::
Expand Down
6 changes: 3 additions & 3 deletions docs/csharp/whats-new/csharp-13.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: What's new in C# 13
description: Get an overview of the new features in C# 13.
ms.date: 01/27/2025
ms.date: 05/29/2025
ms.topic: whats-new
---
# What's new in C# 13
Expand Down Expand Up @@ -71,7 +71,7 @@ You can read the details of the changes in the [proposal specification](~/_cshar

## Implicit index access

The implicit "from the end" index operator, `^`, is now allowed in an object initializer expression. For example, you can now initialize an array in an object initializer as shown in the following code:
The implicit "from the end" index operator, `^`, is now allowed in an object initializer expression for single-dimension collections. For example, you can now initialize a single-dimension array using an object initializer as shown in the following code:

```csharp
public class TimerRemaining
Expand Down Expand Up @@ -103,7 +103,7 @@ In versions before C# 13, the `^` operator can't be used in an object initialize

## `ref` and `unsafe` in iterators and `async` methods

This feature and the following two features enable `ref struct` types to use new constructs. You won't use these unless you write your own `ref struct` types. More likely, you'll see an indirect benefit as <xref:System.Span`1?displayProperty=nameWithType> and <xref:System.ReadOnlySpan`1?displayProperty=nameWithType> gain more functionality.
This feature and the following two features enable `ref struct` types to use new constructs. You won't use these features unless you write your own `ref struct` types. More likely, you'll see an indirect benefit as <xref:System.Span`1?displayProperty=nameWithType> and <xref:System.ReadOnlySpan`1?displayProperty=nameWithType> gain more functionality.

Before C# 13, iterator methods (methods that use `yield return`) and `async` methods couldn't declare local `ref` variables, nor could they have an `unsafe` context.

Expand Down
Loading