Skip to content

Commit

Permalink
Add Collection expressions to the language reference (#36782)
Browse files Browse the repository at this point in the history
* Update TOC

Move programming guide articles on arrays and collections into the language reference section. This set of content will be updated and edited, then collection expressions will be added.

* Move array content

Move all array content into the language reference.

* Move all snippets

Move snippets to the language reference location.

* Update internal links

Run cleanrepo to update redirected links with the new target, and replace absolute links with relative links.

* Edit pass on collections article

Fix open issues on the collection articles, and perform an edit pass to update.

Simplify examples and remove outdated examples. Update text. Instead of listing all collections, refer to articles in the .NET fundamentals and API reference where all collections are listed.

* Edit pass on Arrays article

Edit and update the Arrays article. Remove older outdated samples, update style (both text and code), and fix two open issues:

- Fix #27181 Clarify the default value for array elements.
- Fix #29181 Clarify the row, column for a 2D array.

* rough draft of collection expressions.

* grammar check and build issues

Do a grammar check on the new article, fix build warnings, and add links.

* modify title

The language reference and spec titles were duplicated

* Apply suggestions from code review

Co-authored-by: Genevieve Warren <[email protected]>

* respond to feedback.

---------

Co-authored-by: Genevieve Warren <[email protected]>
  • Loading branch information
BillWagner and gewarren committed Aug 31, 2023
1 parent 02bab08 commit b8f805b
Show file tree
Hide file tree
Showing 43 changed files with 995 additions and 1,645 deletions.
33 changes: 33 additions & 0 deletions .openpublishing.redirection.csharp.json
Original file line number Diff line number Diff line change
Expand Up @@ -1508,6 +1508,34 @@
"source_path_from_root": "/docs/csharp/programming-guide/classes-and-structs/using-structs.md",
"redirect_url": "/dotnet/csharp/language-reference/builtin-types/struct"
},
{
"source_path_from_root": "/docs/csharp/programming-guide/arrays/implicitly-typed-arrays.md",
"redirect_url": "/dotnet/csharp/language-reference/builtin-types/arrays#implicitly-typed-arrays"
},
{
"source_path_from_root": "/docs/csharp/programming-guide/arrays/index.md",
"redirect_url": "/dotnet/csharp/language-reference/builtin-types/arrays"
},
{
"source_path_from_root": "/docs/csharp/programming-guide/arrays/jagged-arrays.md",
"redirect_url": "/dotnet/csharp/language-reference/builtin-types/arrays#jagged-arrays"
},
{
"source_path_from_root": "/docs/csharp/programming-guide/arrays/multidimensional-arrays.md",
"redirect_url": "/dotnet/csharp/language-reference/builtin-types/arrays#multidimensional-arrays"
},
{
"source_path_from_root": "/docs/csharp/programming-guide/arrays/passing-arrays-as-arguments.md",
"redirect_url": "/dotnet/csharp/language-reference/builtin-types/arrays#passing-arrays-as-arguments"
},
{
"source_path_from_root": "/docs/csharp/programming-guide/arrays/single-dimensional-arrays.md",
"redirect_url": "/dotnet/csharp/language-reference/builtin-types/arrays#single-dimensional-arrays"
},
{
"source_path_from_root": "/docs/csharp/programming-guide/arrays/using-foreach-with-arrays.md",
"redirect_url": "/dotnet/csharp/language-reference/builtin-types/arrays"
},
{
"source_path_from_root": "/docs/csharp/programming-guide/concepts/assemblies-gac/friend-assemblies.md",
"redirect_url": "/dotnet/standard/assembly/friend",
Expand Down Expand Up @@ -1638,6 +1666,11 @@
"source_path_from_root": "/docs/csharp/programming-guide/concepts/caller-information.md",
"redirect_url": "/dotnet/csharp/language-reference/attributes/caller-information"
},
{
"source_path_from_root": "/docs/csharp/programming-guide/concepts/collections.md",
"redirect_url": "/dotnet/csharp/language-reference/builtin-types/collections",
"redirect_document_id": true
},
{
"source_path_from_root": "/docs/csharp/programming-guide/concepts/expression-trees/index.md",
"redirect_url": "/dotnet/csharp/advanced-topics/expression-trees/index"
Expand Down
1 change: 1 addition & 0 deletions docfx.json
Original file line number Diff line number Diff line change
Expand Up @@ -829,6 +829,7 @@
"docs/core/tools/**.md": ".NET CLI",
"docs/core/tutorials/**.md": ".NET",
"docs/core/versions/**.md": ".NET",
"docs/csharp/**/**.md": "C#",
"docs/machine-learning/**/**.md": "ML.NET",
"docs/standard/data/sqlite/**/**.md": "Microsoft.Data.Sqlite",
"docs/standard/design-guidelines/**/**.md": "Framework Design Guidelines",
Expand Down
2 changes: 1 addition & 1 deletion docs/csharp/advanced-topics/expression-trees/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Expression trees won't support new expression node types. It would be a breaking
- [Unsafe pointer operations](../../language-reference/unsafe-code.md#pointer-types)
- [`dynamic` operations](../../language-reference/builtin-types/reference-types.md#the-dynamic-type)
- [Coalescing operators with `null` or `default` literal left side, null coalescing assignment](../../language-reference/operators/assignment-operator.md#null-coalescing-assignment), and the [null propagating operator (`?.`)](../../language-reference/operators/null-coalescing-operator.md)
- [Multi-dimensional array initializers](../../programming-guide/arrays/multidimensional-arrays.md), [indexed properties, and dictionary initializers](../../programming-guide/classes-and-structs/object-and-collection-initializers.md#collection-initializers)
- [Multi-dimensional array initializers](../../language-reference/builtin-types/arrays.md#multidimensional-arrays), [indexed properties, and dictionary initializers](../../programming-guide/classes-and-structs/object-and-collection-initializers.md#collection-initializers)
- [`throw` expressions](../../language-reference/statements/exception-handling-statements.md#the-throw-expression)
- Accessing [`static virtual` or `abstract` interface members](../../language-reference/keywords/interface.md#static-abstract-and-virtual-members)
- Lambda expressions that have [attributes](../../language-reference/operators/lambda-expressions.md#attributes)
Expand Down
104 changes: 104 additions & 0 deletions docs/csharp/language-reference/builtin-types/arrays.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
---
title: "Arrays"
description: Store multiple variables of the same type in an array data structure in C#. Declare an array by specifying a type or specify Object to store any type.
ms.date: 08/24/2023
helpviewer_keywords:
- "arrays [C#]"
- "C# language, arrays"
- "single-dimensional arrays [C#]"
- "arrays [C#], single-dimensional"
- "arrays [C#], multidimensional"
- "multidimensional arrays [C#]"
- "jagged arrays [C#]"
- "arrays [C#], jagged"
- "arrays [C#], foreach"
- "foreach statement [C#], using with arrays"
- "arrays [C#], passing as arguments"
- "arrays [C#], implicitly-typed"
- "implicitly-typed arrays [C#]"
- "C# language, implicitly typed arrays"
---
# Arrays

You can store multiple variables of the same type in an array data structure. You declare an array by specifying the type of its elements. If you want the array to store elements of any type, you can specify `object` as its type. In the unified type system of C#, all types, predefined and user-defined, reference types and value types, inherit directly or indirectly from <xref:System.Object>.

```csharp
type[] arrayName;
```

An array has the following properties:

- An array can be [single-dimensional](#single-dimensional-arrays), [multidimensional](#multidimensional-arrays), or [jagged](#jagged-arrays).
- The number of dimensions are set when an array variable is declared. The length of each dimension is established when the array instance is created. These values can't be changed during the lifetime of the instance.
- A jagged array is an array of arrays, and each member array has the default value of `null`.
- Arrays are zero indexed: an array with `n` elements is indexed from `0` to `n-1`.
- Array elements can be of any type, including an array type.
- Array types are [reference types](../keywords/reference-types.md) derived from the abstract base type <xref:System.Array>. All arrays implement <xref:System.Collections.IList> and <xref:System.Collections.IEnumerable>. You can use the [foreach](../statements/iteration-statements.md#the-foreach-statement) statement to iterate through an array. Single-dimensional arrays also implement <xref:System.Collections.Generic.IList%601> and <xref:System.Collections.Generic.IEnumerable%601>.

The elements of an array can be initialized to known values when the array is created. Beginning with C# 12, all of the collection types can be initialized using a [Collection expression](../operators/collection-expressions.md). Elements that aren't initialized are set to the [default value](default-values.md). The default value is the 0-bit pattern. All reference types (including [non-nullable](../../nullable-references.md#known-pitfalls) types), have the values `null`. All value types have the 0-bit patterns. That means the <xref:System.Nullable%601.HasValue?displayProperty=nameWithType> property is `false` and the <xref:System.Nullable%601.Value?displayProperty=nameWithType> property is undefined. In the .NET implementation, the `Value` property throws an exception.

The following example creates single-dimensional, multidimensional, and jagged arrays:

:::code language="csharp" source="./snippets/shared/Arrays.cs" id="DeclareArrays":::

## Single-dimensional arrays

A *single-dimensional array* is a sequence of like elements. You access an element via its *index*. The *index* is its ordinal position in the sequence. The first element in the array is at index `0`. You create a single-dimensional array using the [new](../operators/new-operator.md) operator specifying the array element type and the number of elements. The following example declares and initializes single-dimensional arrays:

:::code language="csharp" source="snippets/shared/Arrays.cs" id="SingleDimensionalArrayDeclaration":::

The first declaration declares an uninitialized array of five integers, from `array[0]` to `array[4]`. The elements of the array are initialized to the [default value](default-values.md) of the element type, `0` for integers. The second declaration declares an array of strings and initializes all seven values of that array. A [foreach statement](../statements/iteration-statements.md#the-foreach-statement) iterates the elements of the `weekday` array and prints all the values. For single-dimensional arrays, the `foreach` statement processes elements in increasing index order, starting with index 0 and ending with index `Length - 1`.

### Pass single-dimensional arrays as arguments

You can pass an initialized single-dimensional array to a method. In the following example, an array of strings is initialized and passed as an argument to a `DisplayArray` method for strings. The method displays the elements of the array. Next, the `ChangeArray` method reverses the array elements, and then the `ChangeArrayElements` method modifies the first three elements of the array. After each method returns, the `DisplayArray` method shows that passing an array by value doesn't prevent changes to the array elements.

:::code language="csharp" source="./snippets/shared/ArrayExample.cs":::

## Multidimensional arrays

Arrays can have more than one dimension. For example, the following declarations create four arrays: two have two dimensions, two have three dimensions. The first two declarations declare the length of each dimension, but don't initialize the values of the array. The second two declarations use an initializer to set the values of each element in the multidimensional array.

:::code language="csharp" source="./snippets/shared/Arrays.cs" id="MultiDimensionalArrayDeclaration":::

For multi-dimensional arrays, elements are traversed such that the indices of the rightmost dimension are incremented first, then the next left dimension, and so on, to the leftmost index. The following example enumerates both a 2D and a 3D array:

:::code language="csharp" source="./snippets/shared/Arrays.cs" id="ForeachMultiDimension":::

In a 2D array, you can think of the left index as the *row* and the right index as the *column*.

However, with multidimensional arrays, using a nested [for](../statements/iteration-statements.md#the-for-statement) loop gives you more control over the order in which to process the array elements:

:::code language="csharp" source="./snippets/shared/Arrays.cs" id="ForMultiDimension":::

### Pass multidimensional arrays as arguments

You pass an initialized multidimensional array to a method in the same way that you pass a one-dimensional array. The following code shows a partial declaration of a print method that accepts a two-dimensional array as its argument. You can initialize and pass a new array in one step, as is shown in the following example. In the following example, a two-dimensional array of integers is initialized and passed to the `Print2DArray` method. The method displays the elements of the array.

:::code language="csharp" source="./snippets/shared/Arrays.cs" id="MultiDimensionParameter":::

## Jagged arrays

A jagged array is an array whose elements are arrays, possibly of different sizes. A jagged array is sometimes called an "array of arrays." Its elements are reference types and are initialized to `null`. The following examples show how to declare, initialize, and access jagged arrays. The first example, `jaggedArray`, is declared in one statement. Each contained array is created in subsequent statements. The second example, `jaggedArray2` is declared and initialized in one statement. It's possible to mix jagged and multidimensional arrays. The final example, `jaggedArray3`, is a declaration and initialization of a single-dimensional jagged array that contains three two-dimensional array elements of different sizes.

:::code language="csharp" source="./snippets/shared/Arrays.cs" id="JaggedArrayDeclaration":::

A jagged array's elements must be initialized before you can use them. Each of the elements is itself an array. It's also possible to use initializers to fill the array elements with values. When you use initializers, you don't need the array size.

This example builds an array whose elements are themselves arrays. Each one of the array elements has a different size.

:::code language="csharp" source="./snippets/shared/Arrays.cs" id="TrulyJagged":::

## Implicitly typed arrays

You can create an implicitly typed array in which the type of the array instance is inferred from the elements specified in the array initializer. The rules for any implicitly typed variable also apply to implicitly typed arrays. For more information, see [Implicitly Typed Local Variables](../../programming-guide/classes-and-structs/implicitly-typed-local-variables.md).

The following examples show how to create an implicitly typed array:

:::code language="csharp" source="./snippets/shared/Arrays.cs" id="LINQAndArrays":::

In the previous example, notice that with implicitly typed arrays, no square brackets are used on the left side of the initialization statement. Also, jagged arrays are initialized by using `new []` just like single-dimensional arrays.

When you create an anonymous type that contains an array, the array must be implicitly typed in the type's object initializer. In the following example, `contacts` is an implicitly typed array of anonymous types, each of which contains an array named `PhoneNumbers`. The `var` keyword isn't used inside the object initializers.

:::code language="csharp" source="./snippets/shared/Arrays.cs" id="LINQInit":::
Loading

0 comments on commit b8f805b

Please sign in to comment.