diff --git a/.openpublishing.redirection.csharp.json b/.openpublishing.redirection.csharp.json index d4f2e5925ffd4..097e99186fd1b 100644 --- a/.openpublishing.redirection.csharp.json +++ b/.openpublishing.redirection.csharp.json @@ -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", @@ -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" diff --git a/docfx.json b/docfx.json index a9f3e0eeb53e7..3edf276b9e8a0 100644 --- a/docfx.json +++ b/docfx.json @@ -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", diff --git a/docs/csharp/advanced-topics/expression-trees/index.md b/docs/csharp/advanced-topics/expression-trees/index.md index 4e636aad76cd9..4dd4bc8448c65 100644 --- a/docs/csharp/advanced-topics/expression-trees/index.md +++ b/docs/csharp/advanced-topics/expression-trees/index.md @@ -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) diff --git a/docs/csharp/language-reference/builtin-types/arrays.md b/docs/csharp/language-reference/builtin-types/arrays.md new file mode 100644 index 0000000000000..ff47c533e2598 --- /dev/null +++ b/docs/csharp/language-reference/builtin-types/arrays.md @@ -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 . + +```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 . All arrays implement and . You can use the [foreach](../statements/iteration-statements.md#the-foreach-statement) statement to iterate through an array. Single-dimensional arrays also implement and . + +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 property is `false` and the 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"::: diff --git a/docs/csharp/language-reference/builtin-types/collections.md b/docs/csharp/language-reference/builtin-types/collections.md new file mode 100644 index 0000000000000..ffeb3e23fdeac --- /dev/null +++ b/docs/csharp/language-reference/builtin-types/collections.md @@ -0,0 +1,79 @@ +--- +title: "Collections" +description: Learn about collections in C#, which are used to work with groups of objects. Collections have different characteristics regarding adding and removing elements, modifying elements, and enumerating the collection elements. +ms.date: 08/22/2023 +--- +# Collections + +The .NET runtime provides many collection types that store and manage groups of related objects. Some of the collection types, such as , , and are recognized in the C# language. In addition, interfaces like are recognized in the language for enumerating the elements of a collection. + +Collections provide a flexible way to work with groups of objects. You can classify different collections by these characteristics: + +- **Element access**: Every collection can be enumerated to access each element in order. Some collections access elements by *index*, the element's position in an ordered collection. The most common example is . Other collections access elements by *key*, where a *value* is associated with a single *key*. The most common example is . You choose between these collection types based on how your app accesses elements. +- **Performance profile**: Every collection has different performance profiles for actions like adding an element, finding an element, or removing an element. You can pick a collection type based on the operations used most in your app. +- **Grow and shrink dynamically**: Most collections supporting adding or removing elements dynamically. Notably, , , and don't. + +In addition to those characteristics, the runtime provides specialized collections that prevent adding or removing elements or modifying the elements of the collection. Other specialized collections provide safety for concurrent access in multi-threaded apps. + +You can find all the collection types in the [.NET API reference](/dotnet/api/?term=collection). For more information, see [Commonly Used Collection Types](../../../standard/collections/commonly-used-collection-types.md) and [Selecting a Collection Class](../../../standard/collections/selecting-a-collection-class.md). + +> [!NOTE] +> For the examples in this article, you might need to add [using directives](../keywords/using-directive.md) for the `System.Collections.Generic` and `System.Linq` namespaces. + +[Arrays](./arrays.md) are represented by and have syntax support in the C# language. This syntax provides more concise declarations for array variables. + + is a [`ref struct`](./ref-struct.md) type that provides a snapshot over a sequence of elements without copying those elements. The compiler enforces safety rules to ensure the `Span` can't be accessed after the sequence it references is no longer in scope. It's used in many .NET APIs to improve performance. provides similar behavior when you can't use a `ref struct` type. + +Beginning with C# 12, all of the collection types can be initialized using a [Collection expression](../operators/collection-expressions.md). + +## Indexable collections + +An *indexable collection* is one where you can access each element using its index. Its *index* is the number of elements before it in the sequence. Therefore, the element reference by index `0` is the first element, index `1` is the second, and so on. These examples use the class. It's the most common indexable collection. + +The following example creates and initializes a list of strings, removes an element, and adds an element to the end of the list. After each modification, it iterates through the strings by using a [foreach](../statements/iteration-statements.md#the-foreach-statement) statement or a `for` loop: + +:::code language="csharp" source="./snippets/shared/Collections.cs" id="SnippetCreateList"::: + +The following example removes elements from a list by index. Instead of a `foreach` statement, it uses a `for` statement that iterates in descending order. The method causes elements after a removed element to have a lower index value. + +:::code language="csharp" source="./snippets/shared/Collections.cs" id="SnippetRemoveItemByIndex"::: + +For the type of elements in the , you can also define your own class. In the following example, the `Galaxy` class that is used by the is defined in the code. + +:::code language="csharp" source="./snippets/shared/Collections.cs" id="SnippetCustomList"::: + +## Key/value pair collections + +These examples use the class. It's the most common dictionary collection. A dictionary collection enables you to access elements in the collection by using the key of each element. Each addition to the dictionary consists of a value and its associated key. + +The following example creates a `Dictionary` collection and iterates through the dictionary by using a `foreach` statement. + +:::code language="csharp" source="./snippets/shared/Collections.cs" id="SnippetDictionary"::: + +The following example uses the method and the property of `Dictionary` to quickly find an item by key. The `Item` property enables you to access an item in the `elements` collection by using the `elements[symbol]` in C#. + +:::code language="csharp" source="./snippets/shared/Collections.cs" id="SnippetFindInDictionary"::: + +The following example instead uses the method to quickly find an item by key. + +:::code language="csharp" source="./snippets/shared/Collections.cs" id="SnippetFindInDictionary2"::: + +## Iterators + +An *iterator* is used to perform a custom iteration over a collection. An iterator can be a method or a `get` accessor. An iterator uses a [yield return](../statements/yield.md) statement to return each element of the collection one at a time. + +You call an iterator by using a [foreach](../statements/iteration-statements.md#the-foreach-statement) statement. Each iteration of the `foreach` loop calls the iterator. When a `yield return` statement is reached in the iterator, an expression is returned, and the current location in code is retained. Execution is restarted from that location the next time that the iterator is called. + +For more information, see [Iterators (C#)](../../programming-guide/concepts/iterators.md). + +The following example uses an iterator method. The iterator method has a `yield return` statement that is inside a `for` loop. In the `ListEvenNumbers` method, each iteration of the `foreach` statement body creates a call to the iterator method, which proceeds to the next `yield return` statement. + +:::code language="csharp" source="./snippets/shared/Collections.cs" id="SnippetIteratorMethod"::: + +## LINQ and collections + +Language-integrated query (LINQ) can be used to access collections. LINQ queries provide filtering, ordering, and grouping capabilities. For more information, see [Getting Started with LINQ in C#](../../linq/index.md). + +The following example runs a LINQ query against a generic `List`. The LINQ query returns a different collection that contains the results. + +:::code language="csharp" source="./snippets/shared/Collections.cs" id="ShowLINQ"::: diff --git a/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/ArrayExample.cs b/docs/csharp/language-reference/builtin-types/snippets/shared/ArrayExample.cs similarity index 95% rename from samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/ArrayExample.cs rename to docs/csharp/language-reference/builtin-types/snippets/shared/ArrayExample.cs index 1e93b24fe3fe6..e86db6d7a0a16 100644 --- a/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/ArrayExample.cs +++ b/docs/csharp/language-reference/builtin-types/snippets/shared/ArrayExample.cs @@ -1,6 +1,4 @@ -using System; - -class ArrayExample +class ArrayExample { static void DisplayArray(string[] arr) => Console.WriteLine(string.Join(" ", arr)); @@ -44,4 +42,4 @@ static void Main() // Sat Fri Thu Wed Tue Mon Sun // // Array weekDays after the call to ChangeArrayElements: -// Mon Wed Fri Wed Tue Mon Sun \ No newline at end of file +// Mon Wed Fri Wed Tue Mon Sun diff --git a/docs/csharp/language-reference/builtin-types/snippets/shared/Arrays.cs b/docs/csharp/language-reference/builtin-types/snippets/shared/Arrays.cs new file mode 100644 index 0000000000000..f1d332f365316 --- /dev/null +++ b/docs/csharp/language-reference/builtin-types/snippets/shared/Arrays.cs @@ -0,0 +1,342 @@ +class TestArraysClass +{ + public static void DeclareArrays() + { + // + // Declare a single-dimensional array of 5 integers. + int[] array1 = new int[5]; + + // Declare and set array element values. + int[] array2 = { 1, 2, 3, 4, 5, 6 }; + + // Declare a two dimensional array. + int[,] multiDimensionalArray1 = new int[2, 3]; + + // Declare and set array element values. + int[,] multiDimensionalArray2 = { { 1, 2, 3 }, { 4, 5, 6 } }; + + // Declare a jagged array. + int[][] jaggedArray = new int[6][]; + + // Set the values of the first array in the jagged array structure. + jaggedArray[0] = new int[4] { 1, 2, 3, 4 }; + // + } + + public static void SingleDimensionalArrays() + { + // + int[] array = new int[5]; + string[] weekDays = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; + + Console.WriteLine(weekDays[0]); + Console.WriteLine(weekDays[1]); + Console.WriteLine(weekDays[2]); + Console.WriteLine(weekDays[3]); + Console.WriteLine(weekDays[4]); + Console.WriteLine(weekDays[5]); + Console.WriteLine(weekDays[6]); + + /*Output: + Sun + Mon + Tue + Wed + Thu + Fri + Sat + */ + // + } + + public static void MultiDimensionalArrays() + { + // + int[,] array2DDeclaration = new int[4, 2]; + + int[,,] array3DDeclaration = new int[4, 2, 3]; + + // Two-dimensional array. + int[,] array2DInitialization = { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } }; + // Three-dimensional array. + int[,,] array3D = new int[,,] { { { 1, 2, 3 }, { 4, 5, 6 } }, + { { 7, 8, 9 }, { 10, 11, 12 } } }; + + // Accessing array elements. + System.Console.WriteLine(array2DInitialization[0, 0]); + System.Console.WriteLine(array2DInitialization[0, 1]); + System.Console.WriteLine(array2DInitialization[1, 0]); + System.Console.WriteLine(array2DInitialization[1, 1]); + + System.Console.WriteLine(array2DInitialization[3, 0]); + System.Console.WriteLine(array2DInitialization[3, 1]); + // Output: + // 1 + // 2 + // 3 + // 4 + // 7 + // 8 + + System.Console.WriteLine(array3D[1, 0, 1]); + System.Console.WriteLine(array3D[1, 1, 2]); + // Output: + // 8 + // 12 + + // Getting the total count of elements or the length of a given dimension. + var allLength = array3D.Length; + var total = 1; + for (int i = 0; i < array3D.Rank; i++) + { + total *= array3D.GetLength(i); + } + System.Console.WriteLine($"{allLength} equals {total}"); + // Output: + // 12 equals 12 + // + } + + //< MultiDimensionParameter> + static void Print2DArray(int[,] arr) + { + // Display the array elements. + for (int i = 0; i < arr.GetLength(0); i++) + { + for (int j = 0; j < arr.GetLength(1); j++) + { + System.Console.WriteLine("Element({0},{1})={2}", i, j, arr[i, j]); + } + } + } + static void ExampleUsage() + { + // Pass the array as an argument. + Print2DArray(new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } }); + } + /* Output: + Element(0,0)=1 + Element(0,1)=2 + Element(1,0)=3 + Element(1,1)=4 + Element(2,0)=5 + Element(2,1)=6 + Element(3,0)=7 + Element(3,1)=8 + */ + // + + public static void ForEachMultiDim() + { + // + int[,] numbers2D = { { 9, 99 }, { 3, 33 }, { 5, 55 } }; + + foreach (int i in numbers2D) + { + System.Console.Write($"{i} "); + } + // Output: 9 99 3 33 5 55 + + int[,,] array3D = new int[,,] { { { 1, 2, 3 }, { 4, 5, 6 } }, + { { 7, 8, 9 }, { 10, 11, 12 } } }; + foreach (int i in array3D) + { + System.Console.Write($"{i} "); + } + // Output: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 + + // + } + + public static void ForMultiDimension() + { + // + int[,,] array3D = new int[,,] { { { 1, 2, 3 }, { 4, 5, 6 } }, + { { 7, 8, 9 }, { 10, 11, 12 } } }; + + for (int i = 0; i < array3D.GetLength(0); i++) + { + for (int j = 0; j < array3D.GetLength(1); j++) + { + for (int k = 0; k < array3D.GetLength(2); k++) + { + System.Console.Write($"{array3D[i, j, k]} "); + } + System.Console.WriteLine(); + } + System.Console.WriteLine(); + } + // Output (including blank lines): + // 1 2 3 + // 4 5 6 + // + // 7 8 9 + // 10 11 12 + // + // + } + + public static void JaggedArrayDeclaration() + { + // + int[][] jaggedArray = new int[3][]; + + jaggedArray[0] = new int[] { 1, 3, 5, 7, 9 }; + jaggedArray[1] = new int[] { 0, 2, 4, 6 }; + jaggedArray[2] = new int[] { 11, 22 }; + + int[][] jaggedArray2 = + { + new int[] { 1, 3, 5, 7, 9 }, + new int[] { 0, 2, 4, 6 }, + new int[] { 11, 22 } + }; + + // Assign 77 to the second element ([1]) of the first array ([0]): + jaggedArray2[0][1] = 77; + + // Assign 88 to the second element ([1]) of the third array ([2]): + jaggedArray2[2][1] = 88; + + int[][,] jaggedArray3 = new int[3][,] + { + new int[,] { {1,3}, {5,7} }, + new int[,] { {0,2}, {4,6}, {8,10} }, + new int[,] { {11,22}, {99,88}, {0,9} } + }; + + Console.Write("{0}", jaggedArray3[0][1, 0]); + Console.WriteLine(jaggedArray3.Length); + // + } + + public static void DifferentSizeJagged() + { + // + // Declare the array of two elements. + int[][] arr = new int[2][]; + + // Initialize the elements. + arr[0] = new int[5] { 1, 3, 5, 7, 9 }; + arr[1] = new int[4] { 2, 4, 6, 8 }; + + // Display the array elements. + for (int i = 0; i < arr.Length; i++) + { + System.Console.Write("Element({0}): ", i); + + for (int j = 0; j < arr[i].Length; j++) + { + System.Console.Write("{0}{1}", arr[i][j], j == (arr[i].Length - 1) ? "" : " "); + } + System.Console.WriteLine(); + } + /* Output: + Element(0): 1 3 5 7 9 + Element(1): 2 4 6 8 + */ + // + } + + public static void ArraysWithLINQ() + { + // + var a = new[] { 1, 10, 100, 1000 }; // int[] + + // Accessing array + Console.WriteLine("First element: " + a[0]); + Console.WriteLine("Second element: " + a[1]); + Console.WriteLine("Third element: " + a[2]); + Console.WriteLine("Fourth element: " + a[3]); + /* Outputs + First element: 1 + Second element: 10 + Third element: 100 + Fourth element: 1000 + */ + + var b = new[] { "hello", null, "world" }; // string[] + + // Accessing elements of an array using 'string.Join' method + Console.WriteLine(string.Join(" ", b)); + /* Output + hello world + */ + + // single-dimension jagged array + var c = new[] + { + new[]{1,2,3,4}, + new[]{5,6,7,8} + }; + // Looping through the outer array + for (int k = 0; k < c.Length; k++) + { + // Looping through each inner array + for (int j = 0; j < c[k].Length; j++) + { + // Accessing each element and printing it to the console + Console.WriteLine($"Element at c[{k}][{j}] is: {c[k][j]}"); + } + } + /* Outputs + Element at c[0][0] is: 1 + Element at c[0][1] is: 2 + Element at c[0][2] is: 3 + Element at c[0][3] is: 4 + Element at c[1][0] is: 5 + Element at c[1][1] is: 6 + Element at c[1][2] is: 7 + Element at c[1][3] is: 8 + */ + + // jagged array of strings + var d = new[] + { + new[]{"Luca", "Mads", "Luke", "Dinesh"}, + new[]{"Karen", "Suma", "Frances"} + }; + + // Looping through the outer array + int i = 0; + foreach (var subArray in d) + { + // Looping through each inner array + int j = 0; + foreach (var element in subArray) + { + // Accessing each element and printing it to the console + Console.WriteLine($"Element at d[{i}][{j}] is: {element}"); + j++; + } + i++; + } + /* Outputs + Element at d[0][0] is: Luca + Element at d[0][1] is: Mads + Element at d[0][2] is: Luke + Element at d[0][3] is: Dinesh + Element at d[1][0] is: Karen + Element at d[1][1] is: Suma + Element at d[1][2] is: Frances + */ + // + } + + public static void Init() + { + // + var contacts = new[] + { + new { + Name = " Eugene Zabokritski", + PhoneNumbers = new[] { "206-555-0108", "425-555-0001" } + }, + new { + Name = " Hanying Feng", + PhoneNumbers = new[] { "650-555-0199" } + } + }; + // + } +} diff --git a/docs/csharp/language-reference/builtin-types/snippets/shared/Collections.cs b/docs/csharp/language-reference/builtin-types/snippets/shared/Collections.cs new file mode 100644 index 0000000000000..961202da31218 --- /dev/null +++ b/docs/csharp/language-reference/builtin-types/snippets/shared/Collections.cs @@ -0,0 +1,218 @@ +namespace CollectionExamples; + +public class Collections +{ + public static void ListExample() + { + // + // Create a list of strings by using a + // collection initializer. + var salmons = new List { "chinook", "coho", "pink", "sockeye" }; + + // Iterate through the list. + foreach (var salmon in salmons) + { + Console.Write(salmon + " "); + } + // Output: chinook coho pink sockeye + + // Remove an element from the list by specifying + // the object. + salmons.Remove("coho"); + + + // Iterate using the index: + for (var index = 0; index < salmons.Count; index++) + { + Console.Write(salmons[index] + " "); + } + // Output: chinook pink sockeye + + // Add the removed element + salmons.Add("coho"); + // Iterate through the list. + foreach (var salmon in salmons) + { + Console.Write(salmon + " "); + } + // Output: chinook pink sockeye coho + // + } + + public static void RemoveByIndex() + { + + // + var numbers = new List { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + + // Remove odd numbers. + for (var index = numbers.Count - 1; index >= 0; index--) + { + if (numbers[index] % 2 == 1) + { + // Remove the element by specifying + // the zero-based index in the list. + numbers.RemoveAt(index); + } + } + + // Iterate through the list. + // A lambda expression is placed in the ForEach method + // of the List(T) object. + numbers.ForEach( + number => Console.Write(number + " ")); + // Output: 0 2 4 6 8 + // + } + + // + private static void IterateThroughList() + { + var theGalaxies = new List + { + new (){ Name="Tadpole", MegaLightYears=400}, + new (){ Name="Pinwheel", MegaLightYears=25}, + new (){ Name="Milky Way", MegaLightYears=0}, + new (){ Name="Andromeda", MegaLightYears=3} + }; + + foreach (Galaxy theGalaxy in theGalaxies) + { + Console.WriteLine(theGalaxy.Name + " " + theGalaxy.MegaLightYears); + } + + // Output: + // Tadpole 400 + // Pinwheel 25 + // Milky Way 0 + // Andromeda 3 + } + + public class Galaxy + { + public string Name { get; set; } + public int MegaLightYears { get; set; } + } + // + + // + private static void IterateThruDictionary() + { + Dictionary elements = BuildDictionary(); + + foreach (KeyValuePair kvp in elements) + { + Element theElement = kvp.Value; + + Console.WriteLine("key: " + kvp.Key); + Console.WriteLine("values: " + theElement.Symbol + " " + + theElement.Name + " " + theElement.AtomicNumber); + } + } + + public class Element + { + public required string Symbol { get; init; } + public required string Name { get; init; } + public required int AtomicNumber { get; init; } + } + + private static Dictionary BuildDictionary() => + new () + { + {"K", + new (){ Symbol="K", Name="Potassium", AtomicNumber=19}}, + {"Ca", + new (){ Symbol="Ca", Name="Calcium", AtomicNumber=20}}, + {"Sc", + new (){ Symbol="Sc", Name="Scandium", AtomicNumber=21}}, + {"Ti", + new (){ Symbol="Ti", Name="Titanium", AtomicNumber=22}} + }; + // + + private static void FindInDictionary(string symbol) + { + Dictionary elements = BuildDictionary(); + + // + if (elements.ContainsKey(symbol) == false) + { + Console.WriteLine(symbol + " not found"); + } + else + { + Element theElement = elements[symbol]; + Console.WriteLine("found: " + theElement.Name); + } + // + } + + private static void FindInDictionary2(string symbol) + { + Dictionary elements = BuildDictionary(); + + // + if (elements.TryGetValue(symbol, out Element? theElement) == false) + Console.WriteLine(symbol + " not found"); + else + Console.WriteLine("found: " + theElement.Name); + // + } + + // + private static void ShowLINQ() + { + List elements = BuildList(); + + // LINQ Query. + var subset = from theElement in elements + where theElement.AtomicNumber < 22 + orderby theElement.Name + select theElement; + + foreach (Element theElement in subset) + { + Console.WriteLine(theElement.Name + " " + theElement.AtomicNumber); + } + + // Output: + // Calcium 20 + // Potassium 19 + // Scandium 21 + } + + private static List BuildList() => new() + { + { new(){ Symbol="K", Name="Potassium", AtomicNumber=19}}, + { new(){ Symbol="Ca", Name="Calcium", AtomicNumber=20}}, + { new(){ Symbol="Sc", Name="Scandium", AtomicNumber=21}}, + { new(){ Symbol="Ti", Name="Titanium", AtomicNumber=22}} + }; + // + + // + private static void ListEvenNumbers() + { + foreach (int number in EvenSequence(5, 18)) + { + Console.Write(number.ToString() + " "); + } + Console.WriteLine(); + // Output: 6 8 10 12 14 16 18 + } + + private static IEnumerable EvenSequence( + int firstNumber, int lastNumber) + { + // Yield even numbers in the range. + for (var number = firstNumber; number <= lastNumber; number++) + { + if (number % 2 == 0) + { + yield return number; + } + } + } + // +} diff --git a/docs/csharp/language-reference/builtin-types/snippets/shared/Program.cs b/docs/csharp/language-reference/builtin-types/snippets/shared/Program.cs index ee9fd0f763e95..bcf7435411118 100644 --- a/docs/csharp/language-reference/builtin-types/snippets/shared/Program.cs +++ b/docs/csharp/language-reference/builtin-types/snippets/shared/Program.cs @@ -4,6 +4,15 @@ class Program { static void Main(string[] args) { + Console.WriteLine("============ Array type ========="); + TestArraysClass.SingleDimensionalArrays(); + TestArraysClass.MultiDimensionalArrays(); + TestArraysClass.ForEachMultiDim(); + TestArraysClass.ForMultiDimension(); + TestArraysClass.JaggedArrayDeclaration(); + TestArraysClass.DifferentSizeJagged(); + TestArraysClass.ArraysWithLINQ(); + Console.WriteLine("======== Unmanaged types ========="); UnmanagedTypes.Main(); Console.WriteLine(); @@ -51,5 +60,6 @@ static void Main(string[] args) Console.WriteLine("====== Native integer types ======"); NativeIntegerTypes.Examples(); Console.WriteLine(); + } } diff --git a/docs/csharp/programming-guide/arrays/snippets/RetrievingArrayElements.cs b/docs/csharp/language-reference/builtin-types/snippets/shared/RetrievingArrayElements.cs similarity index 100% rename from docs/csharp/programming-guide/arrays/snippets/RetrievingArrayElements.cs rename to docs/csharp/language-reference/builtin-types/snippets/shared/RetrievingArrayElements.cs diff --git a/docs/csharp/language-reference/operators/collection-expressions.md b/docs/csharp/language-reference/operators/collection-expressions.md new file mode 100644 index 0000000000000..4d5481e457271 --- /dev/null +++ b/docs/csharp/language-reference/operators/collection-expressions.md @@ -0,0 +1,69 @@ +--- +title: "Collection expressions (Collection literals)" +description: Collection expressions are expressions that convert to many different collection types. They enable you to write literal values for collection elements, or import other collection elements into a new collection. +ms.date: 08/25/2023 +helpviewer_keywords: + - "Collection expressions" +--- +# Collection expressions - C# language reference + +You can use a *collection expression* to create common collection values. A *collection expression* is a terse syntax that, when evaluated, can be assigned to many different collection types. A collection expression contains a sequence of elements between `[` and `]` brackets. The following example declares a of `string` elements and initializes them to the days of the week: + +:::code language="csharp" source="./snippets/shared/CollectionExpressionExamples.cs" id="FirstCollectionExpression"::: + +A *collection expression* can be converted to many different collection types. The first example demonstrated how to initialize a variable using a collection expression. The following code shows many of the other locations where you can use a collection expression: + +:::code language="csharp" source="./snippets/shared/CollectionExpressionExamples.cs" id="CompileTimeExpressions"::: + +You can't use a collection expression where a compile-time constant is expected, such as initializing a constant, or as the default value for a method argument. + +Both of the previous examples used constants as the elements of a collection expression. You can also use variables for the elements as shown in the following example: + +:::code language="csharp" source="./snippets/shared/CollectionExpressionExamples.cs" id="UseVariables"::: + +## Spread element + +You use a *spread element* `..` to inline collection values in a collection expression. The following example creates a collection for the full alphabet by combining a collection of the vowels, a collection of the consonants, and the letter "y", which can be either: + +:::code language="csharp" source="./snippets/shared/CollectionExpressionExamples.cs" id="SpreadOperator"::: + +The spread element `..vowels`, when evaluated, produces five elements: `"a"`, `"e"`, `"i"`, `"o"`, and `"u"`. The spread element `..consonants` produces 20 elements, the number in the `consonants` array. The variable in a spread element must be enumerable using a [`foreach`](../statements/iteration-statements.md#the-foreach-statement) statement. As shown in the previous example, you can combine spread elements with individual elements in a collection expression. + +## Conversions + +A *collection expression* can be converted to different collection types, including: + +- and +- [Inline arrays](../builtin-types/struct.md#inline-arrays) +- [Arrays](../builtin-types/arrays.md) +- Any type with a *create* method whose parameter type is `ReadOnlySpan` where there's an implicit conversion from the collection expression type to `T`. +- Any type that supports a [collection initializer](../../programming-guide/classes-and-structs/object-and-collection-initializers.md#collection-initializers), such as . Usually, this requirement means the type supports and there's an accessible `Add` method to add items to the collection. There must be an implicit conversion from the collection expression elements' type to the collection's element type. For spread elements, there must be an implicit conversion from the spread element's type to the collection's element type. + +Many APIs are overloaded with multiple collection types as parameters. Because a collection expression can be converted to many different expression types, these APIs may require casts on the collection expression to specify the correct conversion. The following conversion rules resolve some of the ambiguities: + +- Conversion to , , or another [`ref struct`](../builtin-types/ref-struct.md) type is better than a conversion to a non-ref struct type. +- Conversion to a noninterface type is better than a conversion to an interface type. + +When a collection expression is converted to a `Span` or `ReadOnlySpan`, the span object's *safe context* is taken from the *safe context* of all elements included in the span. For detailed rules, see the [Collection expression specification](~/_csharplang/proposals/csharp-12.0/collection-expressions.md#ref-safety). + +## Collection builder + +A type opts in to collection expression support by writing a `Create()` method and applying the on the collection type to indicate the builder method. For example, consider an application that uses fixed length buffers of 80 characters. That class might look something like the following code: + +:::code language="csharp" source="./snippets/shared/CollectionExpressionExamples.cs" id="BufferDeclaration"::: + +You'd like to use it with collection expressions as shown in the following sample: + +:::code language="csharp" source="./snippets/shared/CollectionExpressionExamples.cs" id="CustomBuilderUsage"::: + +The `LineBuffer` type implements `IEnumerable`, so the compiler recognizes it as a collection of `char` items. The type parameter of the implemented interface indicates the element type. You need to make two additions to your application to be able to assign collection expressions to a `LineBuffer` object. First, you need to create a class that contains a `Create` method: + +:::code language="csharp" source="./snippets/shared/CollectionExpressionExamples.cs" id="BuilderClass"::: + +The `Create` method must return a `LineBuffer` object, and it must take a single parameter of the type `ReadOnlySpan`. The type parameter of the `ReadOnlySpan` must match the element type of the collection. A builder method that returns a generic collection would have the generic `ReadOnlySpan` as its parameter. The method must be accessible and `static`. + +Finally, you must add the to the `LineBuffer` class declaration: + +:::code language="csharp" source="./snippets/shared/CollectionExpressionExamples.cs" id="BuilderAttribute"::: + +The first parameter provides the name of the *Builder* class. The second attribute provides the name of the builder method. diff --git a/docs/csharp/language-reference/operators/member-access-operators.md b/docs/csharp/language-reference/operators/member-access-operators.md index b75c2e2242ac1..a576265cd73b1 100644 --- a/docs/csharp/language-reference/operators/member-access-operators.md +++ b/docs/csharp/language-reference/operators/member-access-operators.md @@ -78,7 +78,7 @@ If an array index is outside the bounds of the corresponding dimension of an arr As the preceding example shows, you also use square brackets when you declare an array type or instantiate an array instance. -For more information about arrays, see [Arrays](../../programming-guide/arrays/index.md). +For more information about arrays, see [Arrays](../builtin-types/arrays.md). ### Indexer access @@ -228,6 +228,8 @@ The following example demonstrates the effect of using all the ranges presented For more information, see [Indices and ranges](../../tutorials/ranges-indexes.md). +The `..` token is also used as the [spread operator](./collection-expressions.md#spread-element) in a collection expression. + ## Operator overloadability The `.`, `()`, `^`, and `..` operators can't be overloaded. The `[]` operator is also considered a non-overloadable operator. Use [indexers](../../programming-guide/indexers/index.md) to support indexing with user-defined types. diff --git a/docs/csharp/language-reference/operators/new-operator.md b/docs/csharp/language-reference/operators/new-operator.md index a7d872d71e7a3..98666094e6a8a 100644 --- a/docs/csharp/language-reference/operators/new-operator.md +++ b/docs/csharp/language-reference/operators/new-operator.md @@ -42,7 +42,7 @@ Use array initialization syntax to create an array instance and populate it with [!code-csharp-interactive[initialize array](snippets/shared/NewOperator.cs#ArrayInitialization)] -For more information about arrays, see [Arrays](../../programming-guide/arrays/index.md). +For more information about arrays, see [Arrays](../builtin-types/arrays.md). ## Instantiation of anonymous types diff --git a/docs/csharp/language-reference/operators/snippets/shared/CollectionExpressionExamples.cs b/docs/csharp/language-reference/operators/snippets/shared/CollectionExpressionExamples.cs new file mode 100644 index 0000000000000..1683533c85773 --- /dev/null +++ b/docs/csharp/language-reference/operators/snippets/shared/CollectionExpressionExamples.cs @@ -0,0 +1,107 @@ +using System.Collections.Immutable; +using System.Runtime.CompilerServices; +using System.Collections; + + +// +[CollectionBuilder(typeof(LineBufferBuilder), "Create")] +// +// +public class LineBuffer : IEnumerable +{ + private readonly char[] _buffer = new char[80]; + + public LineBuffer(ReadOnlySpan buffer) + { + int number = (_buffer.Length < buffer.Length) ? _buffer.Length : buffer.Length; + for (int i = 0; i < number; i++) + { + _buffer[i] = buffer[i]; + } + } + + public IEnumerator GetEnumerator() => _buffer.AsEnumerable().GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => _buffer.GetEnumerator(); + + // etc +} +// + +// +internal static class LineBufferBuilder +{ + internal static LineBuffer Create(ReadOnlySpan values) => new LineBuffer(values); +} +// + +public class CollectionExpressionExamples +{ + internal static void Examples() + { + // + LineBuffer line = [ 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!' ]; + // + IEnumerator iter = line.GetEnumerator(); + while (iter.MoveNext()) + { + Console.Write(iter.Current); + } + Console.WriteLine(); + + // + Span weekDays = [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ]; + foreach (var day in weekDays) + { + Console.WriteLine(day); + } + // + + // + string hydrogen = "H"; + string helium = "He"; + string lithium = "Li"; + string beryllium = "Be"; + string boron = "B"; + string carbon = "C"; + string nitrogen = "N"; + string oxygen = "O"; + string fluorine = "F"; + string neon = "Ne"; + string[] elements = [ hydrogen, helium, lithium, beryllium, boron, carbon, nitrogen, oxygen, fluorine, neon ]; + foreach (var element in elements) + { + Console.WriteLine(element); + } + // + + // + string[] vowels = [ "a", "e", "i", "o", "u" ]; + string[] consonants = [ "b", "c", "d", "f", "g", "h", "j", "k", "l", "m", + "n", "p", "q", "r", "s", "t", "v", "w", "x", "z" ]; + string[] alphabet = [ ..vowels, ..consonants, "y" ]; + // + } + + + public class Container + { + // + // Initialize private field: + private static readonly ImmutableArray _months = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ]; + + // property with expression body: + public IEnumerable MaxDays => + [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]; + + public int Sum(IEnumerable values) => + values.Sum(); + + public void Example() + { + // As a parameter: + int sum = Sum([1, 2, 3, 4, 5]); + } + // + } +} + diff --git a/docs/csharp/language-reference/operators/snippets/shared/Program.cs b/docs/csharp/language-reference/operators/snippets/shared/Program.cs index b86814da687d6..504183d61649a 100644 --- a/docs/csharp/language-reference/operators/snippets/shared/Program.cs +++ b/docs/csharp/language-reference/operators/snippets/shared/Program.cs @@ -108,3 +108,7 @@ Console.WriteLine("============= is operator example =============="); IsOperator.Examples(); Console.WriteLine(); + +Console.WriteLine("============ Collection expressions ================="); +CollectionExpressionExamples.Examples(); +Console.WriteLine(); diff --git a/docs/csharp/language-reference/operators/snippets/shared/operators.csproj b/docs/csharp/language-reference/operators/snippets/shared/operators.csproj index 45279e4e58e1b..fb2d02c13f3bb 100644 --- a/docs/csharp/language-reference/operators/snippets/shared/operators.csproj +++ b/docs/csharp/language-reference/operators/snippets/shared/operators.csproj @@ -2,7 +2,7 @@ Exe - net7.0 + net8.0 enable true preview diff --git a/docs/csharp/language-reference/statements/iteration-statements.md b/docs/csharp/language-reference/statements/iteration-statements.md index dc7153113a3ff..89fa349561c1e 100644 --- a/docs/csharp/language-reference/statements/iteration-statements.md +++ b/docs/csharp/language-reference/statements/iteration-statements.md @@ -159,5 +159,4 @@ For more information about features added in C# 8.0 and later, see the following ## See also - [C# reference](../index.md) -- [Using foreach with arrays](../../programming-guide/arrays/using-foreach-with-arrays.md) - [Iterators](../../iterators.md) diff --git a/docs/csharp/programming-guide/arrays/implicitly-typed-arrays.md b/docs/csharp/programming-guide/arrays/implicitly-typed-arrays.md deleted file mode 100644 index fcde97c577b91..0000000000000 --- a/docs/csharp/programming-guide/arrays/implicitly-typed-arrays.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: "Implicitly Typed Arrays - C# Programming Guide" -description: The type of an implicitly-typed array in C# is inferred from the elements in the array initializer. Use implicitly-typed arrays in query expressions. -ms.date: 07/20/2015 -helpviewer_keywords: - - "arrays [C#], implicitly-typed" - - "implicitly-typed arrays [C#]" - - "C# language, implicitly typed arrays" -ms.assetid: e05be95c-6732-403d-ae42-b35f057cbbea ---- - -# Implicitly Typed Arrays (C# Programming Guide) - -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](../classes-and-structs/implicitly-typed-local-variables.md). - -Implicitly-typed arrays are usually used in query expressions together with anonymous types and object and collection initializers. - -The following examples show how to create an implicitly-typed array: - -[!code-csharp[csProgGuideLINQ#37](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideLINQ/CS/csRef30LangFeatures_2.cs#37)] - -In the previous example, notice that with implicitly-typed arrays, no square brackets are used on the left side of the initialization statement. Note also that jagged arrays are initialized by using `new []` just like single-dimension arrays. - -## Implicitly-typed Arrays in Object Initializers - -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`. Note that the `var` keyword is not used inside the object initializers. - -[!code-csharp[csProgGuideLINQ#38](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideLINQ/CS/csRef30LangFeatures_2.cs#38)] - -## See also - -- [C# Programming Guide](../index.md) -- [Implicitly Typed Local Variables](../classes-and-structs/implicitly-typed-local-variables.md) -- [Arrays](./index.md) -- [Anonymous Types](../../fundamentals/types/anonymous-types.md) -- [Object and Collection Initializers](../classes-and-structs/object-and-collection-initializers.md) -- [var](../../language-reference/statements/declarations.md#implicitly-typed-local-variables) -- [LINQ in C#](../../linq/index.md) diff --git a/docs/csharp/programming-guide/arrays/index.md b/docs/csharp/programming-guide/arrays/index.md deleted file mode 100644 index 70e5a264894cb..0000000000000 --- a/docs/csharp/programming-guide/arrays/index.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -title: "Arrays - C# Programming Guide" -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: 07/07/2021 -helpviewer_keywords: - - "arrays [C#]" - - "C# language, arrays" -ms.assetid: bb79bdde-e570-4c30-adb0-1dd5759ae041 ---- -# Arrays (C# Programming Guide) - -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 . - -```csharp -type[] arrayName; -``` - -## Example - -The following example creates single-dimensional, multidimensional, and jagged arrays: - -[!code-csharp[csProgGuideArrays#1](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#1)] - -## Array overview - -An array has the following properties: - -- An array can be [single-dimensional](single-dimensional-arrays.md), [multidimensional](multidimensional-arrays.md) or [jagged](jagged-arrays.md). -- The number of dimensions and the length of each dimension are established when the array instance is created. These values can't be changed during the lifetime of the instance. -- The default values of numeric array elements are set to zero, and reference elements are set to `null`. -- A jagged array is an array of arrays, and therefore its elements are reference types and are initialized to `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](../../language-reference/keywords/reference-types.md) derived from the abstract base type . All arrays implement , and . You can use the [foreach](../../language-reference/statements/iteration-statements.md#the-foreach-statement) statement to iterate through an array. Single-dimensional arrays also implement and . - -### Default value behaviour - -- For value types, the array elements are initialized with the [default value](../../language-reference/builtin-types/default-values.md), the 0-bit pattern; the elements will have the value `0`. -- All the reference types (including the [non-nullable](../../nullable-references.md#known-pitfalls)), have the values `null`. -- For nullable value types, `HasValue` is set to `false` and the elements would be set to `null`. - -### Arrays as Objects - -In C#, arrays are actually objects, and not just addressable regions of contiguous memory as in C and C++. is the abstract base type of all array types. You can use the properties and other class members that has. An example of this is using the property to get the length of an array. The following code assigns the length of the `numbers` array, which is `5`, to a variable called `lengthOfNumbers`: - -[!code-csharp[csProgGuideArrays#3](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#3)] - -The class provides many other useful methods and properties for sorting, searching, and copying arrays. The following example uses the property to display the number of dimensions of an array. - -[!code-csharp[csProgGuideArrays#2](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#2)] - -## See also - -- [How to use single-dimensional arrays](single-dimensional-arrays.md) -- [How to use multi-dimensional arrays](multidimensional-arrays.md) -- [How to use jagged arrays](jagged-arrays.md) -- [Using foreach with arrays](using-foreach-with-arrays.md) -- [Passing arrays as arguments](passing-arrays-as-arguments.md) -- [Implicitly typed arrays](implicitly-typed-arrays.md) -- [C# Programming Guide](../index.md) -- [Collections](../concepts/collections.md) - -[!INCLUDE[CSharplangspec](~/includes/csharplangspec-md.md)] diff --git a/docs/csharp/programming-guide/arrays/jagged-arrays.md b/docs/csharp/programming-guide/arrays/jagged-arrays.md deleted file mode 100644 index a0d709af75c39..0000000000000 --- a/docs/csharp/programming-guide/arrays/jagged-arrays.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: Jagged Arrays - C# Programming Guide -description: A jagged array in C# is an array whose elements are arrays of different sizes. Learn how to declare, initialize, and access jagged arrays. -ms.date: 12/18/2020 -helpviewer_keywords: - - "jagged arrays [C#]" - - "arrays [C#], jagged" -ms.assetid: 537c65a6-0e0a-4a00-a2b8-086f38519c70 ---- -# Jagged Arrays (C# Programming Guide) - -A jagged array is an array whose elements are arrays, possibly of different sizes. A jagged array is sometimes called an "array of arrays." The following examples show how to declare, initialize, and access jagged arrays. - - The following is a declaration of a single-dimensional array that has three elements, each of which is a single-dimensional array of integers: - - [!code-csharp[csProgGuideArrays#19](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#19)] - - Before you can use `jaggedArray`, its elements must be initialized. You can initialize the elements like this: - - [!code-csharp[csProgGuideArrays#20](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#20)] - - Each of the elements is a single-dimensional array of integers. The first element is an array of 5 integers, the second is an array of 4 integers, and the third is an array of 2 integers. - - It is also possible to use initializers to fill the array elements with values, in which case you do not need the array size. For example: - - [!code-csharp[csProgGuideArrays#21](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#21)] - - You can also initialize the array upon declaration like this: - - [!code-csharp[csProgGuideArrays#22](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#22)] - - You can use the following shorthand form. Notice that you cannot omit the `new` operator from the elements initialization because there is no default initialization for the elements: - - [!code-csharp[csProgGuideArrays#23](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#23)] - - A jagged array is an array of arrays, and therefore its elements are reference types and are initialized to `null`. - - You can access individual array elements like these examples: - - [!code-csharp[csProgGuideArrays#24](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#24)] - - It's possible to mix jagged and multidimensional arrays. The following is a declaration and initialization of a single-dimensional jagged array that contains three two-dimensional array elements of different sizes. For more information, see [Multidimensional Arrays](./multidimensional-arrays.md). - - [!code-csharp[csProgGuideArrays#25](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#25)] - - You can access individual elements as shown in this example, which displays the value of the element `[1,0]` of the first array (value `5`): - - [!code-csharp[csProgGuideArrays#26](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#26)] - - The method `Length` returns the number of arrays contained in the jagged array. For example, assuming you have declared the previous array, this line: - - [!code-csharp[csProgGuideArrays#27](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#27)] - - returns a value of 3. - -## Example - - This example builds an array whose elements are themselves arrays. Each one of the array elements has a different size. - - [!code-csharp[csProgGuideArrays#18](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#18)] - -## See also - -- -- [C# Programming Guide](../index.md) -- [Arrays](./index.md) -- [Single-Dimensional Arrays](./single-dimensional-arrays.md) -- [Multidimensional Arrays](./multidimensional-arrays.md) diff --git a/docs/csharp/programming-guide/arrays/multidimensional-arrays.md b/docs/csharp/programming-guide/arrays/multidimensional-arrays.md deleted file mode 100644 index 3fdb13fb23d73..0000000000000 --- a/docs/csharp/programming-guide/arrays/multidimensional-arrays.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: "Multidimensional Arrays - C# Programming Guide" -description: Arrays in C# can have more than one dimension. This example declaration creates a two-dimensional array of four rows and two columns. -ms.date: 07/20/2015 -helpviewer_keywords: - - "arrays [C#], multidimensional" - - "multidimensional arrays [C#]" -ms.assetid: 020ce02e-7dff-4273-8e53-bf0b33747232 ---- -# Multidimensional Arrays (C# Programming Guide) - -Arrays can have more than one dimension. For example, the following declaration creates a two-dimensional array of four rows and two columns. - - [!code-csharp[csProgGuideArrays#11](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#11)] - - The following declaration creates an array of three dimensions, 4, 2, and 3. - - [!code-csharp[csProgGuideArrays#12](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#12)] - -## Array Initialization - - You can initialize the array upon declaration, as is shown in the following example. - - [!code-csharp[csProgGuideArrays#13](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#13)] - - You can also initialize the array without specifying the rank. - - [!code-csharp[csProgGuideArrays#14](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#14)] - - If you choose to declare an array variable without initialization, you must use the `new` operator to assign an array to the variable. The use of `new` is shown in the following example. - - [!code-csharp[csProgGuideArrays#15](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#15)] - - The following example assigns a value to a particular array element. - - [!code-csharp[csProgGuideArrays#16](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#16)] - - Similarly, the following example gets the value of a particular array element and assigns it to variable `elementValue`. - - [!code-csharp[csProgGuideArrays#42](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#42)] - - The following code example initializes the array elements to default values (except for jagged arrays). - - [!code-csharp[csProgGuideArrays#17](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#17)] - -## See also - -- [C# Programming Guide](../index.md) -- [Arrays](./index.md) -- [Single-Dimensional Arrays](./single-dimensional-arrays.md) -- [Jagged Arrays](./jagged-arrays.md) diff --git a/docs/csharp/programming-guide/arrays/passing-arrays-as-arguments.md b/docs/csharp/programming-guide/arrays/passing-arrays-as-arguments.md deleted file mode 100644 index d0c15775a82c1..0000000000000 --- a/docs/csharp/programming-guide/arrays/passing-arrays-as-arguments.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -title: "Passing arrays as arguments - C# Programming Guide" -description: Arrays in C# can be passed as arguments to method parameters. Because arrays are reference types, the method can change the value of the elements. -ms.date: 07/05/2018 -helpviewer_keywords: - - "arrays [C#], passing as arguments" -ms.assetid: f3a0971e-c87c-4a1f-8262-bc0a3b712772 ---- -# Passing arrays as arguments (C# Programming Guide) - -Arrays can be passed as arguments to method parameters. Because arrays are reference types, the method can change the value of the elements. - -## Passing single-dimensional arrays as arguments - -You can pass an initialized single-dimensional array to a method. For example, the following statement sends an array to a print method. - -[!code-csharp[csProgGuideArrays#34](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#34)] - -The following code shows a partial implementation of the print method. - -[!code-csharp[csProgGuideArrays#33](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#33)] - -You can initialize and pass a new array in one step, as is shown in the following example. - -[!code-csharp[CsProgGuideArrays#35](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#35)] - -### Example - -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-csharp[csProgGuideArrays#30](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/ArrayExample.cs)] - -## Passing multidimensional arrays as arguments - -You pass an initialized multidimensional array to a method in the same way that you pass a one-dimensional array. - -[!code-csharp[csProgGuideArrays#41](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#41)] - -The following code shows a partial declaration of a print method that accepts a two-dimensional array as its argument. - -[!code-csharp[csProgGuideArrays#36](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#36)] - -You can initialize and pass a new array in one step, as is shown in the following example: - -[!code-csharp[csProgGuideArrays#32](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#32)] - -### 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-csharp[csProgGuideArrays#31](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#31)] - -## See also - -- [C# Programming Guide](../index.md) -- [Arrays](index.md) -- [Single-Dimensional Arrays](single-dimensional-arrays.md) -- [Multidimensional Arrays](multidimensional-arrays.md) -- [Jagged Arrays](jagged-arrays.md) diff --git a/docs/csharp/programming-guide/arrays/single-dimensional-arrays.md b/docs/csharp/programming-guide/arrays/single-dimensional-arrays.md deleted file mode 100644 index 8778e67f9a837..0000000000000 --- a/docs/csharp/programming-guide/arrays/single-dimensional-arrays.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -title: "Single-Dimensional Arrays - C# Programming Guide" -description: Create a single-dimensional array in C# using the new operator specifying the array element type and the number of elements. -ms.date: 06/03/2020 -helpviewer_keywords: - - "single-dimensional arrays [C#]" - - "arrays [C#], single-dimensional" -ms.assetid: 2cec1196-1de0-49d2-baf2-c607c33310e8 ---- -# Single-Dimensional Arrays (C# Programming Guide) - -You create a single-dimensional array using the [new](../../language-reference/operators/new-operator.md) operator specifying the array element type and the number of elements. The following example declares an array of five integers: - -:::code language="csharp" source="snippets/SingleDimensionArrays.cs" id="IntDeclaration"::: - -This array contains the elements from `array[0]` to `array[4]`. The elements of the array are initialized to the [default value](../../language-reference/builtin-types/default-values.md) of the element type, `0` for integers. - -Arrays can store any element type you specify, such as the following example that declares an array of strings: - -:::code language="csharp" source="snippets/SingleDimensionArrays.cs" id="StringDeclaration"::: - -## Array Initialization - -You can initialize the elements of an array when you declare the array. The length specifier isn't needed because it's inferred by the number of elements in the initialization list. For example: - -:::code language="csharp" source="snippets/SingleDimensionArrays.cs" id="IntInitialization"::: - -The following code shows a declaration of a string array where each array element is initialized by a name of a day: - -:::code language="csharp" source="snippets/SingleDimensionArrays.cs" id="StringInitialization"::: - -You can avoid the `new` expression and the array type when you initialize an array upon declaration, as shown in the following code. This is called an [implicitly typed array](implicitly-typed-arrays.md): - -:::code language="csharp" source="snippets/SingleDimensionArrays.cs" id="ShorthandInitialization"::: - -You can declare an array variable without creating it, but you must use the `new` operator when you assign a new array to this variable. For example: - -:::code language="csharp" source="snippets/SingleDimensionArrays.cs" id="DeclareAllocate"::: - -## Value Type and Reference Type Arrays - -Consider the following array declaration: - -:::code language="csharp" source="snippets/SingleDimensionArrays.cs" id="FinalInstantiation"::: - -The result of this statement depends on whether `SomeType` is a value type or a reference type. If it's a value type, the statement creates an array of 10 elements, each of which has the type `SomeType`. If `SomeType` is a reference type, the statement creates an array of 10 elements, each of which is initialized to a null reference. In both instances, the elements are initialized to the default value for the element type. For more information about value types and reference types, see [Value types](../../language-reference/builtin-types/value-types.md) and [Reference types](../../language-reference/keywords/reference-types.md). - -## Retrieving data from Array - -You can retrieve the data of an array by using an index. For example: - -:::code language="csharp" source="snippets/RetrievingArrayElements.cs" id="RetrievingDataArray" interactive="try-dotnet-method"::: - -## See also - -- -- [Arrays](./index.md) -- [Multidimensional Arrays](./multidimensional-arrays.md) -- [Jagged Arrays](./jagged-arrays.md) diff --git a/docs/csharp/programming-guide/arrays/snippets/Program.cs b/docs/csharp/programming-guide/arrays/snippets/Program.cs deleted file mode 100644 index e2bdd3deb1f2a..0000000000000 --- a/docs/csharp/programming-guide/arrays/snippets/Program.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace arrays; - -class Program -{ - static void Main(string[] args) - { - Console.WriteLine("Hello World!"); - } -} diff --git a/docs/csharp/programming-guide/arrays/snippets/SingleDimensionArrays.cs b/docs/csharp/programming-guide/arrays/snippets/SingleDimensionArrays.cs deleted file mode 100644 index 146a8a5ede31b..0000000000000 --- a/docs/csharp/programming-guide/arrays/snippets/SingleDimensionArrays.cs +++ /dev/null @@ -1,49 +0,0 @@ -namespace arrays; - -public static class SingleDimensionArrays -{ - internal struct SomeType - { - string thing; - } - - public static void Examples() - { - Declarations(); - } - - private static void Declarations() - { - // - int[] array = new int[5]; - // - - // - string[] stringArray = new string[6]; - // - - // Declare and set array element values - // - int[] array1 = new int[] { 1, 3, 5, 7, 9 }; - // - - // - string[] weekDays = new string[] { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; - // - - // - int[] array2 = { 1, 3, 5, 7, 9 }; - string[] weekDays2 = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; - // - - // - int[] array3; - array3 = new int[] { 1, 3, 5, 7, 9 }; // OK - //array3 = {1, 3, 5, 7, 9}; // Error - // - - // - SomeType[] array4 = new SomeType[10]; - // - } -} diff --git a/docs/csharp/programming-guide/arrays/snippets/arrays.csproj b/docs/csharp/programming-guide/arrays/snippets/arrays.csproj deleted file mode 100644 index 3897747193834..0000000000000 --- a/docs/csharp/programming-guide/arrays/snippets/arrays.csproj +++ /dev/null @@ -1,10 +0,0 @@ - - - - Exe - net6.0 - enable - enable - - - diff --git a/docs/csharp/programming-guide/arrays/using-foreach-with-arrays.md b/docs/csharp/programming-guide/arrays/using-foreach-with-arrays.md deleted file mode 100644 index f5d21a9ab2bec..0000000000000 --- a/docs/csharp/programming-guide/arrays/using-foreach-with-arrays.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: "Using foreach with arrays - C# Programming Guide" -description: The foreach statement in C# iterates through the elements of an array. For single-dimensional arrays, foreach processes elements in increasing index order. -ms.date: 05/23/2018 -helpviewer_keywords: - - "arrays [C#], foreach" - - "foreach statement [C#], using with arrays" -ms.assetid: 5f2da2a9-1f56-4de5-94cc-e07f4f7a0244 ---- -# Using foreach with arrays (C# Programming Guide) - -The [foreach](../../language-reference/statements/iteration-statements.md#the-foreach-statement) statement provides a simple, clean way to iterate through the elements of an array. - -For single-dimensional arrays, the `foreach` statement processes elements in increasing index order, starting with index 0 and ending with index `Length - 1`: - - [!code-csharp[csProgGuideArrays#28](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#28)] - -For multi-dimensional arrays, elements are traversed such that the indices of the rightmost dimension are increased first, then the next left dimension, and so on to the left: - - [!code-csharp[csProgGuideArrays#29](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs#29)] - -However, with multidimensional arrays, using a nested [for](../../language-reference/statements/iteration-statements.md#the-for-statement) loop gives you more control over the order in which to process the array elements. - -## See also - -- -- [C# Programming Guide](../index.md) -- [Arrays](index.md) -- [Single-Dimensional Arrays](single-dimensional-arrays.md) -- [Multidimensional Arrays](multidimensional-arrays.md) -- [Jagged Arrays](jagged-arrays.md) diff --git a/docs/csharp/programming-guide/classes-and-structs/how-to-use-implicitly-typed-local-variables-and-arrays-in-a-query-expression.md b/docs/csharp/programming-guide/classes-and-structs/how-to-use-implicitly-typed-local-variables-and-arrays-in-a-query-expression.md index 5eceb4bfb95f7..9b744713f5902 100644 --- a/docs/csharp/programming-guide/classes-and-structs/how-to-use-implicitly-typed-local-variables-and-arrays-in-a-query-expression.md +++ b/docs/csharp/programming-guide/classes-and-structs/how-to-use-implicitly-typed-local-variables-and-arrays-in-a-query-expression.md @@ -12,7 +12,7 @@ ms.assetid: 6b7354d2-af79-427a-b6a8-f74eb8fd0b91 You can use implicitly typed local variables whenever you want the compiler to determine the type of a local variable. You must use implicitly typed local variables to store anonymous types, which are often used in query expressions. The following examples illustrate both optional and required uses of implicitly typed local variables in queries. - Implicitly typed local variables are declared by using the [var](../../language-reference/statements/declarations.md#implicitly-typed-local-variables) contextual keyword. For more information, see [Implicitly Typed Local Variables](./implicitly-typed-local-variables.md) and [Implicitly Typed Arrays](../arrays/implicitly-typed-arrays.md). + Implicitly typed local variables are declared by using the [var](../../language-reference/statements/declarations.md#implicitly-typed-local-variables) contextual keyword. For more information, see [Implicitly Typed Local Variables](./implicitly-typed-local-variables.md) and [Implicitly Typed Arrays](../../language-reference/builtin-types/arrays.md#implicitly-typed-arrays). ## Examples diff --git a/docs/csharp/programming-guide/classes-and-structs/implicitly-typed-local-variables.md b/docs/csharp/programming-guide/classes-and-structs/implicitly-typed-local-variables.md index 960762ffeb804..aeb08430a4d14 100644 --- a/docs/csharp/programming-guide/classes-and-structs/implicitly-typed-local-variables.md +++ b/docs/csharp/programming-guide/classes-and-structs/implicitly-typed-local-variables.md @@ -9,7 +9,7 @@ ms.assetid: b9218fb2-ef5d-4814-8a8e-2bc29b0bbc9b --- # Implicitly typed local variables (C# Programming Guide) -Local variables can be declared without giving an explicit type. The `var` keyword instructs the compiler to infer the type of the variable from the expression on the right side of the initialization statement. The inferred type may be a built-in type, an anonymous type, a user-defined type, or a type defined in the .NET class library. For more information about how to initialize arrays with `var`, see [Implicitly Typed Arrays](../arrays/implicitly-typed-arrays.md). +Local variables can be declared without giving an explicit type. The `var` keyword instructs the compiler to infer the type of the variable from the expression on the right side of the initialization statement. The inferred type may be a built-in type, an anonymous type, a user-defined type, or a type defined in the .NET class library. For more information about how to initialize arrays with `var`, see [Implicitly Typed Arrays](../../language-reference/builtin-types/arrays.md#implicitly-typed-arrays). The following examples show various ways in which local variables can be declared with `var`: @@ -88,7 +88,7 @@ The use of `var` helps simplify your code, but its use should be restricted to c ## See also - [C# Reference](../../language-reference/index.md) -- [Implicitly Typed Arrays](../arrays/implicitly-typed-arrays.md) +- [Implicitly Typed Arrays](../../language-reference/builtin-types/arrays.md#implicitly-typed-arrays) - [How to use implicitly typed local variables and arrays in a query expression](how-to-use-implicitly-typed-local-variables-and-arrays-in-a-query-expression.md) - [Anonymous Types](../../fundamentals/types/anonymous-types.md) - [Object and Collection Initializers](object-and-collection-initializers.md) diff --git a/docs/csharp/programming-guide/concepts/collections.md b/docs/csharp/programming-guide/concepts/collections.md deleted file mode 100644 index efd6fd29ee8fd..0000000000000 --- a/docs/csharp/programming-guide/concepts/collections.md +++ /dev/null @@ -1,605 +0,0 @@ ---- -title: "Collections (C#)" -description: Learn about collections in C#, which are used to work with groups of objects. Collections can grow and shrink dynamically as the needs of the application change. -ms.date: 07/20/2015 -ms.assetid: 317d7dc3-8587-4873-8b3e-556f86497939 ---- -# Collections (C#) - -For many applications, you want to create and manage groups of related objects. There are two ways to group objects: by creating arrays of objects, and by creating collections of objects. - -Arrays are most useful for creating and working with a fixed number of strongly typed objects. For information about arrays, see [Arrays](../arrays/index.md). - -Collections provide a more flexible way to work with groups of objects. Unlike arrays, the group of objects you work with can grow and shrink dynamically as the needs of the application change. For some collections, you can assign a key to any object that you put into the collection so that you can quickly retrieve the object by using the key. - -A collection is a class, so you must declare an instance of the class before you can add elements to that collection. - -If your collection contains elements of only one data type, you can use one of the classes in the namespace. A generic collection enforces type safety so that no other data type can be added to it. When you retrieve an element from a generic collection, you do not have to determine its data type or convert it. - -> [!NOTE] -> For the examples in this topic, include [using](../../language-reference/keywords/using-directive.md) directives for the `System.Collections.Generic` and `System.Linq` namespaces. - - **In this topic** - -- [Using a Simple Collection](#BKMK_SimpleCollection) - -- [Kinds of Collections](#BKMK_KindsOfCollections) - - - [System.Collections.Generic Classes](#BKMK_Generic) - - - [System.Collections.Concurrent Classes](#BKMK_Concurrent) - - - [System.Collections Classes](#BKMK_Collections) - -- [Implementing a Collection of Key/Value Pairs](#BKMK_KeyValuePairs) - -- [Using LINQ to Access a Collection](#BKMK_LINQ) - -- [Sorting a Collection](#BKMK_Sorting) - -- [Defining a Custom Collection](#BKMK_CustomCollection) - -- [Iterators](#BKMK_Iterators) - - - -## Using a Simple Collection - -The examples in this section use the generic class, which enables you to work with a strongly typed list of objects. - -The following example creates a list of strings and then iterates through the strings by using a [foreach](../../language-reference/statements/iteration-statements.md#the-foreach-statement) statement. - -```csharp -// Create a list of strings. -var salmons = new List(); -salmons.Add("chinook"); -salmons.Add("coho"); -salmons.Add("pink"); -salmons.Add("sockeye"); - -// Iterate through the list. -foreach (var salmon in salmons) -{ - Console.Write(salmon + " "); -} -// Output: chinook coho pink sockeye -``` - -If the contents of a collection are known in advance, you can use a *collection initializer* to initialize the collection. For more information, see [Object and Collection Initializers](../classes-and-structs/object-and-collection-initializers.md). - -The following example is the same as the previous example, except a collection initializer is used to add elements to the collection. - -```csharp -// Create a list of strings by using a -// collection initializer. -var salmons = new List { "chinook", "coho", "pink", "sockeye" }; - -// Iterate through the list. -foreach (var salmon in salmons) -{ - Console.Write(salmon + " "); -} -// Output: chinook coho pink sockeye -``` - -You can use a [for](../../language-reference/statements/iteration-statements.md#the-for-statement) statement instead of a `foreach` statement to iterate through a collection. You accomplish this by accessing the collection elements by the index position. The index of the elements starts at 0 and ends at the element count minus 1. - -The following example iterates through the elements of a collection by using `for` instead of `foreach`. - -```csharp -// Create a list of strings by using a -// collection initializer. -var salmons = new List { "chinook", "coho", "pink", "sockeye" }; - -for (var index = 0; index < salmons.Count; index++) -{ - Console.Write(salmons[index] + " "); -} -// Output: chinook coho pink sockeye -``` - -The following example removes an element from the collection by specifying the object to remove. - -```csharp -// Create a list of strings by using a -// collection initializer. -var salmons = new List { "chinook", "coho", "pink", "sockeye" }; - -// Remove an element from the list by specifying -// the object. -salmons.Remove("coho"); - -// Iterate through the list. -foreach (var salmon in salmons) -{ - Console.Write(salmon + " "); -} -// Output: chinook pink sockeye -``` - -The following example removes elements from a generic list. Instead of a `foreach` statement, a `for` statement that iterates in descending order is used. This is because the method causes elements after a removed element to have a lower index value. - -```csharp -var numbers = new List { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - -// Remove odd numbers. -for (var index = numbers.Count - 1; index >= 0; index--) -{ - if (numbers[index] % 2 == 1) - { - // Remove the element by specifying - // the zero-based index in the list. - numbers.RemoveAt(index); - } -} - -// Iterate through the list. -// A lambda expression is placed in the ForEach method -// of the List(T) object. -numbers.ForEach( - number => Console.Write(number + " ")); -// Output: 0 2 4 6 8 -``` - -For the type of elements in the , you can also define your own class. In the following example, the `Galaxy` class that is used by the is defined in the code. - -```csharp -private static void IterateThroughList() -{ - var theGalaxies = new List - { - new Galaxy() { Name="Tadpole", MegaLightYears=400}, - new Galaxy() { Name="Pinwheel", MegaLightYears=25}, - new Galaxy() { Name="Milky Way", MegaLightYears=0}, - new Galaxy() { Name="Andromeda", MegaLightYears=3} - }; - - foreach (Galaxy theGalaxy in theGalaxies) - { - Console.WriteLine(theGalaxy.Name + " " + theGalaxy.MegaLightYears); - } - - // Output: - // Tadpole 400 - // Pinwheel 25 - // Milky Way 0 - // Andromeda 3 -} - -public class Galaxy -{ - public string Name { get; set; } - public int MegaLightYears { get; set; } -} -``` - - - -## Kinds of Collections - -Many common collections are provided by .NET. Each type of collection is designed for a specific purpose. - -Some of the common collection classes are described in this section: - -- classes - -- classes - -- classes - - - -### System.Collections.Generic Classes - -You can create a generic collection by using one of the classes in the namespace. A generic collection is useful when every item in the collection has the same data type. A generic collection enforces strong typing by allowing only the desired data type to be added. - -The following table lists some of the frequently used classes of the namespace: - -|Class|Description| -|---|---| -||Represents a collection of key/value pairs that are organized based on the key.| -||Represents a list of objects that can be accessed by index. Provides methods to search, sort, and modify lists.| -||Represents a first in, first out (FIFO) collection of objects.| -||Represents a collection of key/value pairs that are sorted by key based on the associated implementation.| -||Represents a last in, first out (LIFO) collection of objects.| - -For additional information, see [Commonly Used Collection Types](../../../standard/collections/commonly-used-collection-types.md), [Selecting a Collection Class](../../../standard/collections/selecting-a-collection-class.md), and . - - - -### System.Collections.Concurrent Classes - -In .NET Framework 4 and later versions, the collections in the namespace provide efficient thread-safe operations for accessing collection items from multiple threads. - -The classes in the namespace should be used instead of the corresponding types in the and namespaces whenever multiple threads are accessing the collection concurrently. For more information, see [Thread-Safe Collections](../../../standard/collections/thread-safe/index.md) and . - -Some classes included in the namespace are , , , and . - - - -### System.Collections Classes - -The classes in the namespace do not store elements as specifically typed objects, but as objects of type `Object`. - -Whenever possible, you should use the generic collections in the namespace or the namespace instead of the legacy types in the `System.Collections` namespace. - -The following table lists some of the frequently used classes in the `System.Collections` namespace: - -|Class|Description| -|---|---| -||Represents an array of objects whose size is dynamically increased as required.| -||Represents a collection of key/value pairs that are organized based on the hash code of the key.| -||Represents a first in, first out (FIFO) collection of objects.| -||Represents a last in, first out (LIFO) collection of objects.| - -The namespace provides specialized and strongly typed collection classes, such as string-only collections and linked-list and hybrid dictionaries. - - - -## Implementing a Collection of Key/Value Pairs - -The generic collection enables you to access to elements in a collection by using the key of each element. Each addition to the dictionary consists of a value and its associated key. Retrieving a value by using its key is fast because the `Dictionary` class is implemented as a hash table. - -The following example creates a `Dictionary` collection and iterates through the dictionary by using a `foreach` statement. - -```csharp -private static void IterateThruDictionary() -{ - Dictionary elements = BuildDictionary(); - - foreach (KeyValuePair kvp in elements) - { - Element theElement = kvp.Value; - - Console.WriteLine("key: " + kvp.Key); - Console.WriteLine("values: " + theElement.Symbol + " " + - theElement.Name + " " + theElement.AtomicNumber); - } -} - -private static Dictionary BuildDictionary() -{ - var elements = new Dictionary(); - - AddToDictionary(elements, "K", "Potassium", 19); - AddToDictionary(elements, "Ca", "Calcium", 20); - AddToDictionary(elements, "Sc", "Scandium", 21); - AddToDictionary(elements, "Ti", "Titanium", 22); - - return elements; -} - -private static void AddToDictionary(Dictionary elements, - string symbol, string name, int atomicNumber) -{ - Element theElement = new Element(); - - theElement.Symbol = symbol; - theElement.Name = name; - theElement.AtomicNumber = atomicNumber; - - elements.Add(key: theElement.Symbol, value: theElement); -} - -public class Element -{ - public string Symbol { get; set; } - public string Name { get; set; } - public int AtomicNumber { get; set; } -} -``` - -To instead use a collection initializer to build the `Dictionary` collection, you can replace the `BuildDictionary` and `AddToDictionary` methods with the following method. - -```csharp -private static Dictionary BuildDictionary2() -{ - return new Dictionary - { - {"K", - new Element() { Symbol="K", Name="Potassium", AtomicNumber=19}}, - {"Ca", - new Element() { Symbol="Ca", Name="Calcium", AtomicNumber=20}}, - {"Sc", - new Element() { Symbol="Sc", Name="Scandium", AtomicNumber=21}}, - {"Ti", - new Element() { Symbol="Ti", Name="Titanium", AtomicNumber=22}} - }; -} -``` - -The following example uses the method and the property of `Dictionary` to quickly find an item by key. The `Item` property enables you to access an item in the `elements` collection by using the `elements[symbol]` in C#. - -```csharp -private static void FindInDictionary(string symbol) -{ - Dictionary elements = BuildDictionary(); - - if (elements.ContainsKey(symbol) == false) - { - Console.WriteLine(symbol + " not found"); - } - else - { - Element theElement = elements[symbol]; - Console.WriteLine("found: " + theElement.Name); - } -} -``` - -The following example instead uses the method quickly find an item by key. - -```csharp -private static void FindInDictionary2(string symbol) -{ - Dictionary elements = BuildDictionary(); - - Element theElement = null; - if (elements.TryGetValue(symbol, out theElement) == false) - Console.WriteLine(symbol + " not found"); - else - Console.WriteLine("found: " + theElement.Name); -} -``` - - - -## Using LINQ to Access a Collection - -LINQ (Language-Integrated Query) can be used to access collections. LINQ queries provide filtering, ordering, and grouping capabilities. For more information, see [Getting Started with LINQ in C#](/dotnet/csharp/linq/). - -The following example runs a LINQ query against a generic `List`. The LINQ query returns a different collection that contains the results. - -```csharp -private static void ShowLINQ() -{ - List elements = BuildList(); - - // LINQ Query. - var subset = from theElement in elements - where theElement.AtomicNumber < 22 - orderby theElement.Name - select theElement; - - foreach (Element theElement in subset) - { - Console.WriteLine(theElement.Name + " " + theElement.AtomicNumber); - } - - // Output: - // Calcium 20 - // Potassium 19 - // Scandium 21 -} - -private static List BuildList() -{ - return new List - { - { new Element() { Symbol="K", Name="Potassium", AtomicNumber=19}}, - { new Element() { Symbol="Ca", Name="Calcium", AtomicNumber=20}}, - { new Element() { Symbol="Sc", Name="Scandium", AtomicNumber=21}}, - { new Element() { Symbol="Ti", Name="Titanium", AtomicNumber=22}} - }; -} - -public class Element -{ - public string Symbol { get; set; } - public string Name { get; set; } - public int AtomicNumber { get; set; } -} -``` - - - -## Sorting a Collection - -The following example illustrates a procedure for sorting a collection. The example sorts instances of the `Car` class that are stored in a . The `Car` class implements the interface, which requires that the method be implemented. - -Each call to the method makes a single comparison that is used for sorting. User-written code in the `CompareTo` method returns a value for each comparison of the current object with another object. The value returned is less than zero if the current object is less than the other object, greater than zero if the current object is greater than the other object, and zero if they are equal. This enables you to define in code the criteria for greater than, less than, and equal. - -In the `ListCars` method, the `cars.Sort()` statement sorts the list. This call to the method of the causes the `CompareTo` method to be called automatically for the `Car` objects in the `List`. - -```csharp -private static void ListCars() -{ - var cars = new List - { - { new Car() { Name = "car1", Color = "blue", Speed = 20}}, - { new Car() { Name = "car2", Color = "red", Speed = 50}}, - { new Car() { Name = "car3", Color = "green", Speed = 10}}, - { new Car() { Name = "car4", Color = "blue", Speed = 50}}, - { new Car() { Name = "car5", Color = "blue", Speed = 30}}, - { new Car() { Name = "car6", Color = "red", Speed = 60}}, - { new Car() { Name = "car7", Color = "green", Speed = 50}} - }; - - // Sort the cars by color alphabetically, and then by speed - // in descending order. - cars.Sort(); - - // View all of the cars. - foreach (Car thisCar in cars) - { - Console.Write(thisCar.Color.PadRight(5) + " "); - Console.Write(thisCar.Speed.ToString() + " "); - Console.Write(thisCar.Name); - Console.WriteLine(); - } - - // Output: - // blue 50 car4 - // blue 30 car5 - // blue 20 car1 - // green 50 car7 - // green 10 car3 - // red 60 car6 - // red 50 car2 -} - -public class Car : IComparable -{ - public string Name { get; set; } - public int Speed { get; set; } - public string Color { get; set; } - - public int CompareTo(Car other) - { - // A call to this method makes a single comparison that is - // used for sorting. - - // Determine the relative order of the objects being compared. - // Sort by color alphabetically, and then by speed in - // descending order. - - // Compare the colors. - int compare; - compare = String.Compare(this.Color, other.Color, true); - - // If the colors are the same, compare the speeds. - if (compare == 0) - { - compare = this.Speed.CompareTo(other.Speed); - - // Use descending order for speed. - compare = -compare; - } - - return compare; - } -} -``` - - - -## Defining a Custom Collection - -You can define a collection by implementing the or interface. - -Although you can define a custom collection, it is usually better to instead use the collections that are included in .NET, which are described in [Kinds of Collections](#BKMK_KindsOfCollections) earlier in this article. - -The following example defines a custom collection class named `AllColors`. This class implements the interface, which requires that the method be implemented. - -The `GetEnumerator` method returns an instance of the `ColorEnumerator` class. `ColorEnumerator` implements the interface, which requires that the property, method, and method be implemented. - -```csharp -private static void ListColors() -{ - var colors = new AllColors(); - - foreach (Color theColor in colors) - { - Console.Write(theColor.Name + " "); - } - Console.WriteLine(); - // Output: red blue green -} - -// Collection class. -public class AllColors : System.Collections.IEnumerable -{ - Color[] _colors = - { - new Color() { Name = "red" }, - new Color() { Name = "blue" }, - new Color() { Name = "green" } - }; - - public System.Collections.IEnumerator GetEnumerator() - { - return new ColorEnumerator(_colors); - - // Instead of creating a custom enumerator, you could - // use the GetEnumerator of the array. - //return _colors.GetEnumerator(); - } - - // Custom enumerator. - private class ColorEnumerator : System.Collections.IEnumerator - { - private Color[] _colors; - private int _position = -1; - - public ColorEnumerator(Color[] colors) - { - _colors = colors; - } - - object System.Collections.IEnumerator.Current - { - get - { - return _colors[_position]; - } - } - - bool System.Collections.IEnumerator.MoveNext() - { - _position++; - return (_position < _colors.Length); - } - - void System.Collections.IEnumerator.Reset() - { - _position = -1; - } - } -} - -// Element class. -public class Color -{ - public string Name { get; set; } -} -``` - - - -## Iterators - -An *iterator* is used to perform a custom iteration over a collection. An iterator can be a method or a `get` accessor. An iterator uses a [yield return](../../language-reference/statements/yield.md) statement to return each element of the collection one at a time. - -You call an iterator by using a [foreach](../../language-reference/statements/iteration-statements.md#the-foreach-statement) statement. Each iteration of the `foreach` loop calls the iterator. When a `yield return` statement is reached in the iterator, an expression is returned, and the current location in code is retained. Execution is restarted from that location the next time that the iterator is called. - -For more information, see [Iterators (C#)](./iterators.md). - -The following example uses an iterator method. The iterator method has a `yield return` statement that is inside a `for` loop. In the `ListEvenNumbers` method, each iteration of the `foreach` statement body creates a call to the iterator method, which proceeds to the next `yield return` statement. - -```csharp -private static void ListEvenNumbers() -{ - foreach (int number in EvenSequence(5, 18)) - { - Console.Write(number.ToString() + " "); - } - Console.WriteLine(); - // Output: 6 8 10 12 14 16 18 -} - -private static IEnumerable EvenSequence( - int firstNumber, int lastNumber) -{ - // Yield even numbers in the range. - for (var number = firstNumber; number <= lastNumber; number++) - { - if (number % 2 == 0) - { - yield return number; - } - } -} -``` - -## See also - -- [Object and Collection Initializers](../classes-and-structs/object-and-collection-initializers.md) -- [Programming Concepts (C#)](./index.md) -- [Option Strict Statement](../../../visual-basic/language-reference/statements/option-strict-statement.md) -- [LINQ to Objects (C#)](../../linq/query-a-collection-of-objects.md) -- [Parallel LINQ (PLINQ)](../../../standard/parallel-programming/introduction-to-plinq.md) -- [Collections and Data Structures](../../../standard/collections/index.md) -- [Selecting a Collection Class](../../../standard/collections/selecting-a-collection-class.md) -- [Comparisons and Sorts Within Collections](../../../standard/collections/comparisons-and-sorts-within-collections.md) -- [When to Use Generic Collections](../../../standard/collections/when-to-use-generic-collections.md) -- [Iteration statements](../../language-reference/statements/iteration-statements.md) diff --git a/docs/csharp/programming-guide/concepts/index.md b/docs/csharp/programming-guide/concepts/index.md index 3652b23e48061..04eb4f5740d91 100644 --- a/docs/csharp/programming-guide/concepts/index.md +++ b/docs/csharp/programming-guide/concepts/index.md @@ -12,7 +12,6 @@ This section explains programming concepts in the C# language. |Title|Description| |-----------|-----------------| methods, and properties by using attributes.| -|[Collections (C#)](./collections.md)|Describes some of the types of collections provided by .NET. Demonstrates how to use simple collections and collections of key/value pairs.| |[Covariance and Contravariance (C#)](./covariance-contravariance/index.md)|Shows how to enable implicit conversion of generic type parameters in interfaces and delegates.| |[Iterators (C#)](./iterators.md)|Describes iterators, which are used to step through collections and return elements one at a time.| |[Language-Integrated Query (LINQ) (C#)](/dotnet/csharp/linq/)|Discusses the powerful query capabilities in the language syntax of C#, and the model for querying relational databases, XML documents, datasets, and in-memory collections.| diff --git a/docs/csharp/programming-guide/concepts/iterators.md b/docs/csharp/programming-guide/concepts/iterators.md index b1a2fb0569afd..845a166a5c068 100644 --- a/docs/csharp/programming-guide/concepts/iterators.md +++ b/docs/csharp/programming-guide/concepts/iterators.md @@ -354,5 +354,4 @@ Iterators enable you to maintain the simplicity of a `foreach` loop when you nee - - - [foreach, in](../../language-reference/statements/iteration-statements.md#the-foreach-statement) -- [Using foreach with Arrays](../arrays/using-foreach-with-arrays.md) - [Generics](../../fundamentals/types/generics.md) diff --git a/docs/csharp/programming-guide/generics/generics-and-arrays.md b/docs/csharp/programming-guide/generics/generics-and-arrays.md index c90fcffa9ac01..aab28c5b9cc70 100644 --- a/docs/csharp/programming-guide/generics/generics-and-arrays.md +++ b/docs/csharp/programming-guide/generics/generics-and-arrays.md @@ -20,5 +20,5 @@ Single-dimensional arrays that have a lower bound of zero automatically implemen - - [C# Programming Guide](../index.md) - [Generics](../../fundamentals/types/generics.md) -- [Arrays](../arrays/index.md) +- [Arrays](../../language-reference/builtin-types/arrays.md) - [Generics](../../../standard/generics/index.md) diff --git a/docs/csharp/programming-guide/index.md b/docs/csharp/programming-guide/index.md index faf8ce6da173a..8db032b4c1b1a 100644 --- a/docs/csharp/programming-guide/index.md +++ b/docs/csharp/programming-guide/index.md @@ -37,8 +37,6 @@ This section provides detailed information on key C# language features and featu [Delegates](./delegates/index.md) - [Arrays](./arrays/index.md) - [Strings](./strings/index.md) [Properties](./classes-and-structs/properties.md) @@ -57,8 +55,6 @@ This section provides detailed information on key C# language features and featu [Assemblies in .NET](../../standard/assembly/index.md) - [Collections](./concepts/collections.md) - [Exceptions and Exception Handling](../fundamentals/exceptions/index.md) ## See also diff --git a/docs/csharp/toc.yml b/docs/csharp/toc.yml index 5a99fe77ef630..6f1a7ff6e209e 100644 --- a/docs/csharp/toc.yml +++ b/docs/csharp/toc.yml @@ -544,8 +544,6 @@ items: - name: Overview displayName: programming concepts href: programming-guide/concepts/index.md - - name: Collections - href: programming-guide/concepts/collections.md - name: Covariance and contravariance items: - name: Overview @@ -704,23 +702,6 @@ items: href: programming-guide/delegates/how-to-combine-delegates-multicast-delegates.md - name: "How to declare, instantiate, and use a delegate" href: programming-guide/delegates/how-to-declare-instantiate-and-use-a-delegate.md - - name: Arrays - items: - - name: Overview - displayName: arrays - href: programming-guide/arrays/index.md - - name: Single-Dimensional Arrays - href: programming-guide/arrays/single-dimensional-arrays.md - - name: Multidimensional Arrays - href: programming-guide/arrays/multidimensional-arrays.md - - name: Jagged Arrays - href: programming-guide/arrays/jagged-arrays.md - - name: Using foreach with Arrays - href: programming-guide/arrays/using-foreach-with-arrays.md - - name: Passing Arrays as Arguments - href: programming-guide/arrays/passing-arrays-as-arguments.md - - name: Implicitly Typed Arrays - href: programming-guide/arrays/implicitly-typed-arrays.md - name: Strings items: - name: Programming with strings @@ -832,6 +813,12 @@ items: - name: Nullable reference types href: language-reference/builtin-types/nullable-reference-types.md displayName: "? token, ? symbol" + - name: Collections and arrays + items: + - name: Collections + href: language-reference/builtin-types/collections.md + - name: Arrays + href: language-reference/builtin-types/arrays.md - name: void href: language-reference/builtin-types/void.md - name: Built-in types @@ -1015,6 +1002,9 @@ items: - name: Bitwise and shift operators href: language-reference/operators/bitwise-and-shift-operators.md displayName: "~, &, |, ^, <<, >>, &=, |=, ^=, <<=, >>=, AND, XOR, OR" + - name: Collection expressions + displayName: Collection literal, ".. token", ".. symbol", "[] token", "[] symbol" + href: language-reference/operators/collection-expressions.md - name: Equality operators href: language-reference/operators/equality-operators.md displayName: ==, != diff --git a/docs/csharp/tour-of-csharp/features.md b/docs/csharp/tour-of-csharp/features.md index 3048c067398c5..9878fc2a52193 100644 --- a/docs/csharp/tour-of-csharp/features.md +++ b/docs/csharp/tour-of-csharp/features.md @@ -13,7 +13,7 @@ C# and .NET provide many different collection types. Arrays have syntax defined ### Arrays -An [***array***](../programming-guide/arrays/index.md) is a data structure that contains a number of variables that are accessed through computed indices. The variables contained in an array, also called the ***elements*** of the array, are all of the same type. This type is called the ***element type*** of the array. +An [***array***](../language-reference/builtin-types/arrays.md) is a data structure that contains a number of variables that are accessed through computed indices. The variables contained in an array, also called the ***elements*** of the array, are all of the same type. This type is called the ***element type*** of the array. Array types are reference types, and the declaration of an array variable simply sets aside space for a reference to an array instance. Actual array instances are created dynamically at run time using the `new` operator. The `new` operation specifies the ***length*** of the new array instance, which is then fixed for the lifetime of the instance. The indices of the elements of an array range from `0` to `Length - 1`. The `new` operator automatically initializes the elements of an array to their default value, which, for example, is zero for all numeric types and `null` for all reference types. diff --git a/docs/csharp/tour-of-csharp/index.md b/docs/csharp/tour-of-csharp/index.md index 783dced4cdd1d..4130e7ed03a31 100644 --- a/docs/csharp/tour-of-csharp/index.md +++ b/docs/csharp/tour-of-csharp/index.md @@ -77,7 +77,7 @@ The following outline provides an overview of C#'s type system. - User-defined types of the form `class C {...}` - [Interface types](../language-reference/keywords/interface.md) - User-defined types of the form `interface I {...}` - - [Array types](../programming-guide/arrays/index.md) + - [Array types](../language-reference/builtin-types/arrays.md) - Single-dimensional, multi-dimensional, and jagged. For example: `int[]`, `int[,]`, and `int[][]` - [Delegate types](../language-reference/builtin-types/reference-types.md#the-delegate-type) - User-defined types of the form `delegate int D(...)` diff --git a/docs/csharp/whats-new/csharp-12.md b/docs/csharp/whats-new/csharp-12.md index b8cee783cc17d..1de2fede3853c 100644 --- a/docs/csharp/whats-new/csharp-12.md +++ b/docs/csharp/whats-new/csharp-12.md @@ -70,7 +70,7 @@ foreach (var element in single) The operand of a spread operator is an expression that can be enumerated. The spread operator evaluates each element of the enumerations expression. -You can use collection expressions anywhere you need a collection of elements. They can specify the initial value for a collection or be passed as arguments to methods that take collection types. You can learn more about collection expressions in the [feature specification](~/_csharplang/proposals/csharp-12.0/collection-expressions.md). +You can use collection expressions anywhere you need a collection of elements. They can specify the initial value for a collection or be passed as arguments to methods that take collection types. You can learn more about collection expressions in the [language reference article on collection expressions](../language-reference/operators/collection-expressions.md) or the [feature specification](~/_csharplang/proposals/csharp-12.0/collection-expressions.md). ## Default lambda parameters diff --git a/docs/fundamentals/code-analysis/quality-rules/ca1814.md b/docs/fundamentals/code-analysis/quality-rules/ca1814.md index 19a4f3a40143f..291c40970050e 100644 --- a/docs/fundamentals/code-analysis/quality-rules/ca1814.md +++ b/docs/fundamentals/code-analysis/quality-rules/ca1814.md @@ -30,7 +30,7 @@ A member is declared as a multidimensional array, which can result in wasted spa ## Rule description -In a [multidimensional array](../../../csharp/programming-guide/arrays/multidimensional-arrays.md), each element in each dimension has the same, fixed size as the other elements in that dimension. In a [jagged array](../../../csharp/programming-guide/arrays/jagged-arrays.md), which is an array of arrays, each inner array can be of a different size. By only using the space that's needed for a given array, no space is wasted. This rule, CA1814, recommends switching to a jagged array to conserve memory. +In a [multidimensional array](../../../csharp/language-reference/builtin-types/arrays.md#multidimensional-arrays), each element in each dimension has the same, fixed size as the other elements in that dimension. In a [jagged array](../../../csharp/language-reference/builtin-types/arrays.md#jagged-arrays), which is an array of arrays, each inner array can be of a different size. By only using the space that's needed for a given array, no space is wasted. This rule, CA1814, recommends switching to a jagged array to conserve memory. ## How to fix violations diff --git a/docs/standard/serialization/system-text-json/supported-collection-types.md b/docs/standard/serialization/system-text-json/supported-collection-types.md index c2cfb29e2380b..0e7d9907ea16b 100644 --- a/docs/standard/serialization/system-text-json/supported-collection-types.md +++ b/docs/standard/serialization/system-text-json/supported-collection-types.md @@ -28,9 +28,9 @@ The following sections are organized by namespace and show which types are suppo | Type | Serialization | Deserialization | |-------------------------------------------------------------------------------------------------|---------------|-----------------| -| [Single-dimensional arrays](../../../csharp/programming-guide/arrays/single-dimensional-arrays.md) | ✔️ | ✔️ | -| [Multi-dimensional arrays](../../../csharp/programming-guide/arrays/multidimensional-arrays.md) | ❌ | ❌ | -| [Jagged arrays](../../../csharp/programming-guide/arrays/jagged-arrays.md) | ✔️ | ✔️ | +| [Single-dimensional arrays](../../../csharp/language-reference/builtin-types/arrays.md#single-dimensional-arrays) | ✔️ | ✔️ | +| [Multi-dimensional arrays](../../../csharp/language-reference/builtin-types/arrays.md#multidimensional-arrays) | ❌ | ❌ | +| [Jagged arrays](../../../csharp/language-reference/builtin-types/arrays.md#jagged-arrays) | ✔️ | ✔️ | ## System.Collections namespace diff --git a/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs b/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs deleted file mode 100644 index a8c02b8af7a71..0000000000000 --- a/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.cs +++ /dev/null @@ -1,441 +0,0 @@ -using System.Linq; - -// -class TestRef -{ - static void FillArray(ref int[] arr) - { - // Create the array on demand. - arr ??= new int[10]; - // Fill the array. - arr[0] = 1111; - arr[4] = 5555; - } - - static void Main() - { - // Initialize the array. - int[] theArray = { 1, 2, 3, 4, 5 }; - - // Pass the array using ref. - FillArray(ref theArray); - - // Display the updated array. - System.Console.WriteLine("Array elements are:"); - for (int i = 0; i < theArray.Length; i++) - { - System.Console.Write(theArray[i] + " "); - } - - // Keep the console window open in debug mode. - System.Console.WriteLine("Press any key to exit."); - System.Console.ReadKey(); - } -} -/* Output: - Array elements are: - 1111 2 3 4 5555 -*/ -// - -// -class TestOut -{ - static void FillArray(out int[] arr) - { - // Initialize the array. - arr = new int[5] { 1, 2, 3, 4, 5 }; - } - - static void Main() - { - int[] theArray; // Initialization is not required - - // Pass the array to the callee using out. - FillArray(out theArray); - - // Display the array elements. - System.Console.WriteLine("Array elements are:"); - for (int i = 0; i < theArray.Length; i++) - { - System.Console.Write(theArray[i] + " "); - } - - // Keep the console window open in debug mode. - System.Console.WriteLine("Press any key to exit."); - System.Console.ReadKey(); - } -} -/* Output: - Array elements are: - 1 2 3 4 5 -*/ -// - -class TestPrintArray1D -{ - int[] theArray = new int[] { 1, 3, 5, 7, 9 }; - - // - void PrintArray(int[] arr) - { - // Method code. - } - // - - void Test() - { - // - int[] theArray = { 1, 3, 5, 7, 9 }; - PrintArray(theArray); - // - - // - PrintArray(new int[] { 1, 3, 5, 7, 9 }); - // - } -} - -class TestPrintArray2D -{ - int[,] theArray = { { 1, 2 }, { 2, 3 }, { 3, 4 } }; - - // - void Print2DArray(int[,] arr) - { - // Method code. - } - // - - void Test() - { - // - int[,] theArray = { { 1, 2 }, { 2, 3 }, { 3, 4 } }; - Print2DArray(theArray); - // - } -} - -// -class ArrayClass2D -{ - static void Print2DArray(int[,] arr) - { - // Display the array elements. - for (int i = 0; i < arr.GetLength(0); i++) - { - for (int j = 0; j < arr.GetLength(1); j++) - { - System.Console.WriteLine("Element({0},{1})={2}", i, j, arr[i, j]); - } - } - } - static void Main() - { - // Pass the array as an argument. - // - Print2DArray(new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } }); - // - - // Keep the console window open in debug mode. - System.Console.WriteLine("Press any key to exit."); - System.Console.ReadKey(); - } -} -/* Output: - Element(0,0)=1 - Element(0,1)=2 - Element(1,0)=3 - Element(1,1)=4 - Element(2,0)=5 - Element(2,1)=6 - Element(3,0)=7 - Element(3,1)=8 -*/ -// - -class Test3 -{ - static void Main() - { - // - int[] numbers = { 4, 5, 6, 1, 2, 3, -2, -1, 0 }; - foreach (int i in numbers) - { - System.Console.Write("{0} ", i); - } - // Output: 4 5 6 1 2 3 -2 -1 0 - // - - System.Console.WriteLine(); - - // - int[,] numbers2D = new int[3, 2] { { 9, 99 }, { 3, 33 }, { 5, 55 } }; - // Or use the short form: - // int[,] numbers2D = { { 9, 99 }, { 3, 33 }, { 5, 55 } }; - - foreach (int i in numbers2D) - { - System.Console.Write("{0} ", i); - } - // Output: 9 99 3 33 5 55 - // - } - - // - static void TestMethod1(out int[] arr) - { - arr = new int[10]; // definite assignment of arr - } - // - - // - static void TestMethod2(ref int[] arr) - { - arr = new int[10]; // arr initialized to a different array - } - // -} - -class Test1 -{ - void test() - { - // - int[] numbers = { 1, 2, 3, 4, 5 }; - int lengthOfNumbers = numbers.Length; - // - } -} - -class SomeType -{ -} - -class Test2 -{ - void test() - { - // - int[,] array = new int[4, 2]; - // - - // - int[,,] array1 = new int[4, 2, 3]; - // - - // - // Two-dimensional array. - int[,] array2D = new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } }; - // The same array with dimensions specified. - int[,] array2Da = new int[4, 2] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } }; - // A similar array with string elements. - string[,] array2Db = new string[3, 2] { { "one", "two" }, { "three", "four" }, - { "five", "six" } }; - - // Three-dimensional array. - int[,,] array3D = new int[,,] { { { 1, 2, 3 }, { 4, 5, 6 } }, - { { 7, 8, 9 }, { 10, 11, 12 } } }; - // The same array with dimensions specified. - int[,,] array3Da = new int[2, 2, 3] { { { 1, 2, 3 }, { 4, 5, 6 } }, - { { 7, 8, 9 }, { 10, 11, 12 } } }; - - // Accessing array elements. - System.Console.WriteLine(array2D[0, 0]); - System.Console.WriteLine(array2D[0, 1]); - System.Console.WriteLine(array2D[1, 0]); - System.Console.WriteLine(array2D[1, 1]); - System.Console.WriteLine(array2D[3, 0]); - System.Console.WriteLine(array2Db[1, 0]); - System.Console.WriteLine(array3Da[1, 0, 1]); - System.Console.WriteLine(array3D[1, 1, 2]); - - // Getting the total count of elements or the length of a given dimension. - var allLength = array3D.Length; - var total = 1; - for (int i = 0; i < array3D.Rank; i++) - { - total *= array3D.GetLength(i); - } - System.Console.WriteLine("{0} equals {1}", allLength, total); - - // Output: - // 1 - // 2 - // 3 - // 4 - // 7 - // three - // 8 - // 12 - // 12 equals 12 - // - - // - int[,] array4 = { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } }; - // - - // - int[,] array5; - array5 = new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } }; // OK - //array5 = {{1,2}, {3,4}, {5,6}, {7,8}}; // Error - // - - // - array5[2, 1] = 25; - // - - // - int elementValue = array5[2, 1]; - // - //Console.WriteLine(elementValue); - - // - int[,] array6 = new int[10, 10]; - // - } -} - -// -class TestArraysClass -{ - static void Main() - { - // Declare a single-dimensional array of 5 integers. - int[] array1 = new int[5]; - - // Declare and set array element values. - int[] array2 = new int[] { 1, 3, 5, 7, 9 }; - - // Alternative syntax. - int[] array3 = { 1, 2, 3, 4, 5, 6 }; - - // Declare a two dimensional array. - int[,] multiDimensionalArray1 = new int[2, 3]; - - // Declare and set array element values. - int[,] multiDimensionalArray2 = { { 1, 2, 3 }, { 4, 5, 6 } }; - - // Declare a jagged array. - int[][] jaggedArray = new int[6][]; - - // Set the values of the first array in the jagged array structure. - jaggedArray[0] = new int[4] { 1, 2, 3, 4 }; - } -} -// - -namespace WrapTestArraysClass -{ - // - class TestArraysClass - { - static void Main() - { - // Declare and initialize an array. - int[,] theArray = new int[5, 10]; - System.Console.WriteLine("The array has {0} dimensions.", theArray.Rank); - } - } - // Output: The array has 2 dimensions. - // -} - -// -class ArrayTest -{ - static void Main() - { - // Declare the array of two elements. - int[][] arr = new int[2][]; - - // Initialize the elements. - arr[0] = new int[5] { 1, 3, 5, 7, 9 }; - arr[1] = new int[4] { 2, 4, 6, 8 }; - - // Display the array elements. - for (int i = 0; i < arr.Length; i++) - { - System.Console.Write("Element({0}): ", i); - - for (int j = 0; j < arr[i].Length; j++) - { - System.Console.Write("{0}{1}", arr[i][j], j == (arr[i].Length - 1) ? "" : " "); - } - System.Console.WriteLine(); - } - // Keep the console window open in debug mode. - System.Console.WriteLine("Press any key to exit."); - System.Console.ReadKey(); - } -} -/* Output: - Element(0): 1 3 5 7 9 - Element(1): 2 4 6 8 -*/ -// - -class TestJagged -{ - void test() - { - // - int[][] jaggedArray = new int[3][]; - // - - // - jaggedArray[0] = new int[5]; - jaggedArray[1] = new int[4]; - jaggedArray[2] = new int[2]; - // - - // - jaggedArray[0] = new int[] { 1, 3, 5, 7, 9 }; - jaggedArray[1] = new int[] { 0, 2, 4, 6 }; - jaggedArray[2] = new int[] { 11, 22 }; - // - - // - int[][] jaggedArray2 = new int[][] - { - new int[] { 1, 3, 5, 7, 9 }, - new int[] { 0, 2, 4, 6 }, - new int[] { 11, 22 } - }; - // - - // - int[][] jaggedArray3 = - { - new int[] { 1, 3, 5, 7, 9 }, - new int[] { 0, 2, 4, 6 }, - new int[] { 11, 22 } - }; - // - - // - // Assign 77 to the second element ([1]) of the first array ([0]): - jaggedArray3[0][1] = 77; - - // Assign 88 to the second element ([1]) of the third array ([2]): - jaggedArray3[2][1] = 88; - // - - // - int[][,] jaggedArray4 = new int[3][,] - { - new int[,] { {1,3}, {5,7} }, - new int[,] { {0,2}, {4,6}, {8,10} }, - new int[,] { {11,22}, {99,88}, {0,9} } - }; - // - - // - System.Console.Write("{0}", jaggedArray4[0][1, 0]); - // - - // - System.Console.WriteLine(jaggedArray4.Length); - // - } -} diff --git a/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.csproj b/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.csproj deleted file mode 100644 index f45bdfccce254..0000000000000 --- a/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideArrays/CS/Arrays.csproj +++ /dev/null @@ -1,7 +0,0 @@ - - - - netstandard2.1 - - - diff --git a/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideLINQ/CS/csRef30LangFeatures_2.cs b/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideLINQ/CS/csRef30LangFeatures_2.cs index 71757b865b6c6..f9846780024f8 100644 --- a/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideLINQ/CS/csRef30LangFeatures_2.cs +++ b/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideLINQ/CS/csRef30LangFeatures_2.cs @@ -300,116 +300,6 @@ public override string ToString() // } - // Implicitly Typed Arrays example 1 - // - class ImplicitlyTypedArraySample - { - static void Main() - { - var a = new[] { 1, 10, 100, 1000 }; // int[] - - // Accessing array - Console.WriteLine("First element: " + a[0]); - Console.WriteLine("Second element: " + a[1]); - Console.WriteLine("Third element: " + a[2]); - Console.WriteLine("Fourth element: " + a[3]); - /* Outputs - First element: 1 - Second element: 10 - Third element: 100 - Fourth element: 1000 - */ - - var b = new[] { "hello", null, "world" }; // string[] - - // Accessing elements of an array using 'string.Join' method - Console.WriteLine(string.Join(" ", b)); - /* Output - hello world - */ - - // single-dimension jagged array - var c = new[] - { - new[]{1,2,3,4}, - new[]{5,6,7,8} - }; - // Looping through the outer array - for (int k = 0; k < c.Length; k++) - { - // Looping through each inner array - for (int j = 0; j < c[k].Length; j++) - { - // Accessing each element and printing it to the console - Console.WriteLine($"Element at c[{k}][{j}] is: {c[k][j]}"); - } - } - /* Outputs - Element at c[0][0] is: 1 - Element at c[0][1] is: 2 - Element at c[0][2] is: 3 - Element at c[0][3] is: 4 - Element at c[1][0] is: 5 - Element at c[1][1] is: 6 - Element at c[1][2] is: 7 - Element at c[1][3] is: 8 - */ - - // jagged array of strings - var d = new[] - { - new[]{"Luca", "Mads", "Luke", "Dinesh"}, - new[]{"Karen", "Suma", "Frances"} - }; - - // Looping through the outer array - int i = 0; - foreach (var subArray in d) - { - // Looping through each inner array - int j = 0; - foreach (var element in subArray) - { - // Accessing each element and printing it to the console - Console.WriteLine($"Element at d[{i}][{j}] is: {element}"); - j++; - } - i++; - } - /* Outputs - Element at d[0][0] is: Luca - Element at d[0][1] is: Mads - Element at d[0][2] is: Luke - Element at d[0][3] is: Dinesh - Element at d[1][0] is: Karen - Element at d[1][1] is: Suma - Element at d[1][2] is: Frances - */ - } - } - // - - // Implicitly Typed Arrays examples 2 - class ImplicitArraySample2 - { - static void Method() - { - // - var contacts = new[] - { - new { - Name = " Eugene Zabokritski", - PhoneNumbers = new[] { "206-555-0108", "425-555-0001" } - }, - new { - Name = " Hanying Feng", - PhoneNumbers = new[] { "650-555-0199" } - } - }; - // - } - } - //Object and collection initializers //