Skip to content

Fresh-a-pa-looza #40033

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs/core/tutorials/top-level-templates.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "C# console app template changes in .NET 6+"
description: The .NET 6+ project template for C# console apps uses top-level statements. Understand what changed and how to use existing learning materials with the new syntax.
ms.date: 11/08/2022
ms.date: 03/15/2024
---
# C# console app template generates top-level statements

Expand Down Expand Up @@ -36,7 +36,7 @@ In the preceding code, the actual namespace depends on the project name.

These two forms represent the same program. Both are valid with C# 10.0. When you use the newer version, you only need to write the body of the `Main` method. The compiler generates a `Program` class with an entry point method and places all your top level statements in that method. The name of the generated method isn't `Main`, it's an implementation detail that your code can't reference directly. You don't need to include the other program elements, the compiler generates them for you. You can learn more about the code the compiler generates when you use top level statements in the article on [top level statements](../../csharp/fundamentals/program-structure/top-level-statements.md) in the C# Guide's fundamentals section.

You have two options to work with tutorials that haven't been updated to use .NET 6+ templates:
You have two options to work with tutorials that aren't updated to use .NET 6+ templates:

- Use the new program style, adding new top-level statements as you add features.
- Convert the new program style to the older style, with a `Program` class and a `Main` method.
Expand All @@ -59,7 +59,7 @@ You can learn more about top-level statements in the tutorial exploration on [to

## Implicit `using` directives

The term *implicit `using` directives* means the compiler automatically adds a set of [`using` directives](../../csharp/language-reference/keywords/using-directive.md) based on the project type. For console applications, the following directives are implicitly included in the application:
The term *implicit `using` directives* means the compiler automatically adds a set of [`using` directives](../../csharp/language-reference/keywords/using-directive.md) based on the project type. For console applications, the following directives are implicitly included in the application:

- `using System;`
- `using System.IO;`
Expand Down Expand Up @@ -129,7 +129,7 @@ class Program

### Use the old program style in Visual Studio

01. When you create a new project, the setup steps will navigate to the **Additional information** setup page. On this page, select the **Do not use top-level statements** check box.
01. When you create a new project, the setup steps navigate to the **Additional information** setup page. On this page, select the **Do not use top-level statements** check box.

:::image type="content" source="media/top-level-templates/vs-additional-information.png" alt-text="Visual Studio do not use top-level statements check box":::

Expand Down
4 changes: 2 additions & 2 deletions docs/csharp/how-to/concatenate-multiple-strings.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "How to concatenate multiple strings (C# Guide)"
description: There are multiple ways to concatenate strings in C#. Learn the options and the reasons behind different choices.
ms.date: 06/30/2021
ms.date: 03/15/2024
helpviewer_keywords:
- "joining strings [C#]"
- "concatenating strings [C#]"
Expand Down Expand Up @@ -51,7 +51,7 @@ You can read more about the [reasons to choose string concatenation or the `Stri

## `String.Concat` or `String.Join`

Another option to join strings from a collection is to use <xref:System.String.Concat%2A?displayProperty=nameWithType> method. Use <xref:System.String.Join%2A?displayProperty=nameWithType> method if source strings should be separated by a delimiter. The following code combines an array of words using both methods:
Another option to join strings from a collection is to use <xref:System.String.Concat%2A?displayProperty=nameWithType> method. Use <xref:System.String.Join%2A?displayProperty=nameWithType> method if a delimiter should separate source strings. The following code combines an array of words using both methods:

:::code language="csharp" interactive="try-dotnet-method" source="../../../samples/snippets/csharp/how-to/strings/Concatenate.cs" id="Snippet5":::

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "Extension Methods - C# Programming Guide"
description: Extension methods in C# enable you to add methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type.
ms.date: 03/19/2020
ms.date: 03/15/2024
helpviewer_keywords:
- "methods [C#], adding to existing types"
- "extension methods [C#]"
Expand All @@ -21,7 +21,7 @@ The following example shows how to call the standard query operator `OrderBy` me

[!code-csharp[csProgGuideExtensionMethods#3](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideExtensionMethods/cs/extensionmethods.cs#3)]

Extension methods are defined as static methods but are called by using instance method syntax. Their first parameter specifies which type the method operates on. The parameter is preceded by the [this](../../language-reference/keywords/this.md) modifier. Extension methods are only in scope when you explicitly import the namespace into your source code with a `using` directive.
Extension methods are defined as static methods but are called by using instance method syntax. Their first parameter specifies which type the method operates on. The parameter follows the [this](../../language-reference/keywords/this.md) modifier. Extension methods are only in scope when you explicitly import the namespace into your source code with a `using` directive.

The following example shows an extension method defined for the <xref:System.String?displayProperty=nameWithType> class. It's defined inside a non-nested, non-generic static class:

Expand All @@ -40,7 +40,7 @@ string s = "Hello Extension Methods";
int i = s.WordCount();
```

You invoke the extension method in your code with instance method syntax. The intermediate language (IL) generated by the compiler translates your code into a call on the static method. The principle of encapsulation is not really being violated. Extension methods cannot access private variables in the type they are extending.
You invoke the extension method in your code with instance method syntax. The intermediate language (IL) generated by the compiler translates your code into a call on the static method. The principle of encapsulation isn't really being violated. Extension methods can't access private variables in the type they're extending.

Both the `MyExtensions` class and the `WordCount` method are `static`, and it can be accessed like all other `static` members. The `WordCount` method can be invoked like other `static` methods as follows:

Expand All @@ -52,7 +52,7 @@ int i = MyExtensions.WordCount(s);
The preceding C# code:

- Declares and assigns a new `string` named `s` with a value of `"Hello Extension Methods"`.
- Calls `MyExtensions.WordCount` given argument `s`
- Calls `MyExtensions.WordCount` given argument `s`.

For more information, see [How to implement and call a custom extension method](./how-to-implement-and-call-a-custom-extension-method.md).

Expand All @@ -66,7 +66,7 @@ using System.Linq;

## Binding Extension Methods at Compile Time

You can use extension methods to extend a class or interface, but not to override them. An extension method with the same name and signature as an interface or class method will never be called. At compile time, extension methods always have lower priority than instance methods defined in the type itself. In other words, if a type has a method named `Process(int i)`, and you have an extension method with the same signature, the compiler will always bind to the instance method. When the compiler encounters a method invocation, it first looks for a match in the type's instance methods. If no match is found, it will search for any extension methods that are defined for the type, and bind to the first extension method that it finds.
You can use extension methods to extend a class or interface, but not to override them. An extension method with the same name and signature as an interface or class method will never be called. At compile time, extension methods always have lower priority than instance methods defined in the type itself. In other words, if a type has a method named `Process(int i)`, and you have an extension method with the same signature, the compiler will always bind to the instance method. When the compiler encounters a method invocation, it first looks for a match in the type's instance methods. If no match is found, it searches for any extension methods that are defined for the type, and bind to the first extension method that it finds.

## Example

Expand Down Expand Up @@ -107,7 +107,7 @@ static class DomainEntityExtensions

Rather than creating new objects when reusable functionality needs to be created, we can often extend an existing type, such as a .NET or CLR type. As an example, if we don't use extension methods, we might create an `Engine` or `Query` class to do the work of executing a query on a SQL Server that may be called from multiple places in our code. However we can instead extend the <xref:System.Data.SqlClient.SqlConnection?displayProperty=nameWithType> class using extension methods to perform that query from anywhere we have a connection to a SQL Server. Other examples might be to add common functionality to the <xref:System.String?displayProperty=nameWithType> class, extend the data processing capabilities of the <xref:System.IO.Stream?displayProperty=nameWithType> object, and <xref:System.Exception?displayProperty=nameWithType> objects for specific error handling functionality. These types of use-cases are limited only by your imagination and good sense.

Extending predefined types can be difficult with `struct` types because they're passed by value to methods. That means any changes to the struct are made to a copy of the struct. Those changes aren't visible once the extension method exits. You can add the `ref` modifier to the first argument making it a `ref` extension method. The `ref` keyword can appear before or after the `this` keyword without any semantic differences. Adding the `ref` modifier indicates that the first argument is passed by reference. This enables you to write extension methods that change the state of the struct being extended (note that private members are not accessible). Only value types or generic types constrained to struct (see [`struct` constraint](../../language-reference/builtin-types/struct.md#struct-constraint) for more information) are allowed as the first parameter of a `ref` extension method. The following example shows how to use a `ref` extension method to directly modify a built-in type without the need to reassign the result or pass it through a function with the `ref` keyword:
Extending predefined types can be difficult with `struct` types because they're passed by value to methods. That means any changes to the struct are made to a copy of the struct. Those changes aren't visible once the extension method exits. You can add the `ref` modifier to the first argument making it a `ref` extension method. The `ref` keyword can appear before or after the `this` keyword without any semantic differences. Adding the `ref` modifier indicates that the first argument is passed by reference. This enables you to write extension methods that change the state of the struct being extended (note that private members aren't accessible). Only value types or generic types constrained to struct (see [`struct` constraint](../../language-reference/builtin-types/struct.md#struct-constraint) for more information) are allowed as the first parameter of a `ref` extension method. The following example shows how to use a `ref` extension method to directly modify a built-in type without the need to reassign the result or pass it through a function with the `ref` keyword:

:::code language="csharp" source="./snippets/methods/Program.cs" id="Snippet9":::

Expand All @@ -125,7 +125,7 @@ When using an extension method to extend a type whose source code you aren't in

If you do implement extension methods for a given type, remember the following points:

- An extension method will never be called if it has the same signature as a method defined in the type.
- An extension method is not called if it has the same signature as a method defined in the type.
- Extension methods are brought into scope at the namespace level. For example, if you have multiple static classes that contain extension methods in a single namespace named `Extensions`, they'll all be brought into scope by the `using Extensions;` directive.

For a class library that you implemented, you shouldn't use extension methods to avoid incrementing the version number of an assembly. If you want to add significant functionality to a library for which you own the source code, follow the .NET guidelines for assembly versioning. For more information, see [Assembly Versioning](../../../standard/assembly/versioning.md).
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "How to initialize a dictionary with a collection initializer - C# Programming Guide"
description: Learn how to initialize a dictionary in C#, using either the Add method or an index initializer. This example shows both options.
ms.date: 12/20/2018
ms.date: 03/15/2024
helpviewer_keywords:
- "collection initializers [C#], with Dictionary"
ms.topic: how-to
Expand All @@ -24,11 +24,11 @@ A <xref:System.Collections.Generic.Dictionary%602> contains a collection of key/

## Example

In the following code example, a <xref:System.Collections.Generic.Dictionary%602> is initialized with instances of type `StudentName`. The first initialization uses the `Add` method with two arguments. The compiler generates a call to `Add` for each of the pairs of `int` keys and `StudentName` values. The second uses a public read / write indexer method of the `Dictionary` class:
In the following code example, a <xref:System.Collections.Generic.Dictionary%602> is initialized with instances of type `StudentName`. The first initialization uses the `Add` method with two arguments. The compiler generates a call to `Add` for each of the pairs of `int` keys and `StudentName` values. The second uses a public read / write indexer method of the `Dictionary` class:

[!code-csharp[InitializerExample](../../../../samples/snippets/csharp/programming-guide/classes-and-structs/object-collection-initializers/HowToDictionaryInitializer.cs#HowToDictionaryInitializer)]

Note the two pairs of braces in each element of the collection in the first declaration. The innermost braces enclose the object initializer for the `StudentName`, and the outermost braces enclose the initializer for the key/value pair that will be added to the `students` <xref:System.Collections.Generic.Dictionary%602>. Finally, the whole collection initializer for the dictionary is enclosed in braces. In the second initialization, the left side of the assignment is the key and the right side is the value, using an object initializer for `StudentName`.
Note the two pairs of braces in each element of the collection in the first declaration. The innermost braces enclose the object initializer for the `StudentName`, and the outermost braces enclose the initializer for the key/value pair to be added to the `students` <xref:System.Collections.Generic.Dictionary%602>. Finally, the whole collection initializer for the dictionary is enclosed in braces. In the second initialization, the left side of the assignment is the key and the right side is the value, using an object initializer for `StudentName`.

## See also

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "Properties - C# Programming Guide"
description: A property in C# is a member that uses accessor methods to read, write, or compute the value of a private field as if it were a public data member.
ms.date: 07/28/2022
ms.date: 03/15/2024
f1_keywords:
- "cs.properties"
helpviewer_keywords:
Expand All @@ -16,7 +16,7 @@ A property is a member that provides a flexible mechanism to read, write, or com

- Properties enable a class to expose a public way of getting and setting values, while hiding implementation or verification code.
- A [get](../../language-reference/keywords/get.md) property accessor is used to return the property value, and a [set](../../language-reference/keywords/set.md) property accessor is used to assign a new value. An [init](../../language-reference/keywords/init.md) property accessor is used to assign a new value only during object construction. These accessors can have different access levels. For more information, see [Restricting Accessor Accessibility](./restricting-accessor-accessibility.md).
- The [value](../../language-reference/keywords/value.md) keyword is used to define the value being assigned by the `set` or `init` accessor.
- The [value](../../language-reference/keywords/value.md) keyword is used to define the value the `set` or `init` accessor is assigning.
- Properties can be *read-write* (they have both a `get` and a `set` accessor), *read-only* (they have a `get` accessor but no `set` accessor), or *write-only* (they have a `set` accessor, but no `get` accessor). Write-only properties are rare and are most commonly used to restrict access to sensitive data.
- Simple properties that require no custom accessor code can be implemented either as expression body definitions or as [auto-implemented properties](./auto-implemented-properties.md).

Expand Down
Loading