Skip to content

Commit

Permalink
Merge pull request #44055 from dotnet/main
Browse files Browse the repository at this point in the history
Merge main into live
  • Loading branch information
dotnet-policy-service[bot] authored Dec 22, 2024
2 parents 2c45abe + 5d01b47 commit 6d25c7b
Show file tree
Hide file tree
Showing 16 changed files with 532 additions and 747 deletions.
24 changes: 14 additions & 10 deletions docs/csharp/language-reference/configure-language-version.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ ms.date: 09/17/2024

# Configure C# language version

The information in this article applies to .NET 5 and above. For UWP projects, see this information in the article on [Choosing a UWP version](/windows/uwp/updates-and-versions/choose-a-uwp-version).

In Visual Studio, the option to change the language version through the UI is disabled because the default version is aligned with the project's target framework (`TFM`). This default configuration ensures compatibility between language features and runtime support. To change the language version in Visual Studio, change the project's target framework.

For example, changing the target `TFM` (for example, from [.NET 6](https://dotnet.microsoft.com/en-us/download/dotnet/6.0) to [.NET 9](https://dotnet.microsoft.com/en-us/download/dotnet/9.0)) updates the language version accordingly, from C# 10 to C# 13. This approach prevents issues with runtime compatibility and minimizes unexpected build errors due to unsupported language features.

If you need a specific language version that differs from the one automatically selected, refer to the methods in this article to override the default settings directly in the project file.

> [!WARNING]
>
> Setting the `LangVersion` element to `latest` is discouraged. The `latest` setting means the installed compiler uses its latest version. That can change from machine to machine, making builds unreliable. In addition, it enables language features that may require runtime or library features not included in the current SDK.
Expand All @@ -20,15 +28,7 @@ If you must specify your C# version explicitly, you can do so in several ways:
> [!TIP]
> You can see the language version in Visual Studio in the project properties page. Under the *Build* tab, the *Advanced* pane displays the version selected.
>
> To know what language version you're currently using, put `#error version` (case sensitive) in your code. This makes the compiler report a compiler error, CS8304, with a message containing the compiler version being used and the current selected language version. See [#error (C# Reference)](preprocessor-directives.md#error-and-warning-information) for more information.
## Why you can't select a different C# version in Visual Studio

In Visual Studio, the option to change the language version through the UI might be disabled because the default version is aligned with the project's target framework (`TFM`). This default configuration ensures compatibility between language features and runtime support.

For example, changing the target `TFM` (for example, from [.NET 6](https://dotnet.microsoft.com/en-us/download/dotnet/6.0) to [.NET 9](https://dotnet.microsoft.com/en-us/download/dotnet/9.0)) will update the language version accordingly, from C# 10 to C# 13. This approach prevents issues with runtime compatibility and minimizes unexpected build errors due to unsupported language features.

If you need a specific language version that differs from the one automatically selected, refer to the methods below to override the default settings directly in the project file.
> To know what language version you're currently using, put `#error version` (case sensitive) in your code. This makes the compiler report a compiler error, CS8304, with a message containing the compiler version being used and the current selected language version. For more information about this pragma, see [#error (C# Reference)](preprocessor-directives.md#error-and-warning-information).
## Edit the project file

Expand All @@ -44,7 +44,7 @@ The value `preview` uses the latest available preview C# language version that y

## Configure multiple projects

To configure multiple projects, you can create a *Directory.Build.props* file, typically in your solution directory, that contains the `<LangVersion>` element. Add the following setting to the *Directory.Build.props* file:
To configure multiple C# projects, you can create a *Directory.Build.props* file, typically in your solution directory, that contains the `<LangVersion>` element. Add the following setting to the *Directory.Build.props* file:

```xml
<Project>
Expand All @@ -56,6 +56,10 @@ To configure multiple projects, you can create a *Directory.Build.props* file, t

Builds in all subdirectories of the directory containing that file now use the preview C# version. For more information, see [Customize your build](/visualstudio/msbuild/customize-your-build).

> [!NOTE]
>
> The versions for C# and VB are different. Don't use the *Directory.Build.Props* file for a folder where subdirectories contain projects for both languages. The versions won't match.
## C# language version reference

> [!IMPORTANT]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
---
title: "Delegates with Named vs. Anonymous Methods"
description: Learn about delegates with named vs. anonymous methods. See code examples and view additional available resources.
ms.date: 11/22/2024
description: Learn about delegates with named vs. anonymous methods. See code examples and view other available resources.
ms.date: 12/20/2024
helpviewer_keywords:
- "delegates [C#], with named vs. anonymous methods"
- "methods [C#], in delegates"
ms.assetid: 98fa8c61-66b6-4146-986c-3236c4045733
---
# Delegates with Named vs. Anonymous Methods (C# Programming Guide)

A [delegate](../../language-reference/builtin-types/reference-types.md) can be associated with a named method. When you instantiate a delegate by using a named method, the method is passed as a parameter, for example:

[!code-csharp[csProgGuideDelegates#1](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideDelegates/CS/Delegates.cs#1)]
:::code language="csharp" source="./snippets/NamedAnonymousDelegates.cs" id="NamedDelegate":::

This is called using a named method. Delegates constructed with a named method can encapsulate either a [static](../../language-reference/keywords/static.md) method or an instance method. Named methods are the only way to instantiate a delegate in earlier versions of C#. However, in a situation where creating a new method is unwanted overhead, C# enables you to instantiate a delegate and immediately specify a code block that the delegate will process when it is called. The block can contain either a [lambda expression](../../language-reference/operators/lambda-expressions.md) or an [anonymous method](../../language-reference/operators/delegate-operator.md).
The preceding example uses a named method. Delegates constructed with a named method can encapsulate either a [static](../../language-reference/keywords/static.md) method or an instance method. Named methods are the only way to instantiate a delegate in earlier versions of C#. C# enables you to instantiate a delegate and immediately specify a code block that the delegate processes when called. The block can contain either a [lambda expression](../../language-reference/operators/lambda-expressions.md) or an [anonymous method](../../language-reference/operators/delegate-operator.md), as shown in the following example:

The method that you pass as a delegate parameter must have the same signature as the delegate declaration. A delegate instance may encapsulate either static or instance method.
:::code language="csharp" source="./snippets/NamedAnonymousDelegates.cs" id="SnippetAnonymousMethod":::

The method that you pass as a delegate parameter must have the same signature as the delegate declaration. A delegate instance can encapsulate either static or instance method.

> [!NOTE]
> Although the delegate can use an [out](../../language-reference/keywords/method-parameters.md#out-parameter-modifier) parameter, we do not recommend its use with multicast event delegates because you cannot know which delegate will be called.
Method groups with a single overload have a *natural type*. This means the compiler can infer the return type and parameter types for the delegate type:
Method groups with a single overload have a *natural type*. The compiler can infer the return type and parameter types for the delegate type:

```csharp
var read = Console.Read; // Just one overload; Func<int> inferred
Expand All @@ -29,13 +30,13 @@ var write = Console.Write; // ERROR: Multiple overloads, can't choose

## Examples

The following is a simple example of declaring and using a delegate. Notice that both the delegate, `MultiplyCallback`, and the associated method, `MultiplyNumbers`, have the same signature
The following example is a simple example of declaring and using a delegate. Notice that both the delegate, `MultiplyCallback`, and the associated method, `MultiplyNumbers`, have the same signature

[!code-csharp[csProgGuideDelegates#2](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideDelegates/CS/Delegates.cs#2)]
:::code language="csharp" source="./snippets/NamedAnonymousDelegates.cs" id="DeclareAndUse":::

In the following example, one delegate is mapped to both static and instance methods and returns specific information from each.

[!code-csharp[csProgGuideDelegates#3](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideDelegates/CS/Delegates.cs#3)]
:::code language="csharp" source="./snippets/NamedAnonymousDelegates.cs" id="AnotherSample":::

## See also

Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
---
title: "How to combine delegates (Multicast Delegates)"
description: Learn how to combine delegates to create multicast delegates. See a code example and view additional available resources.
description: Learn how to combine delegates to create multicast delegates. See a code example and view more available resources.
ms.topic: how-to
ms.date: 07/20/2015
ms.date: 12/20/2024
helpviewer_keywords:
- "delegates [C#], combining"
- "multicast delegates [C#]"
ms.assetid: 4e689450-6d0c-46de-acfd-f961018ae5dd
---
# How to combine delegates (Multicast Delegates) (C# Programming Guide)

This example demonstrates how to create multicast delegates. A useful property of [delegate](../../language-reference/builtin-types/reference-types.md) objects is that multiple objects can be assigned to one delegate instance by using the `+` operator. The multicast delegate contains a list of the assigned delegates. When the multicast delegate is called, it invokes the delegates in the list, in order. Only delegates of the same type can be combined.

The `-` operator can be used to remove a component delegate from a multicast delegate.

## Example
This example demonstrates how to create multicast delegates. A useful property of [delegate](../../language-reference/builtin-types/reference-types.md) objects is that multiple objects can be assigned to one delegate instance by using the `+` operator. The multicast delegate contains a list of the assigned delegates. When the multicast delegate is called, it invokes the delegates in the list, in order. Only delegates of the same type can be combined. The `-` operator can be used to remove a component delegate from a multicast delegate.

:::code language="csharp" source="./snippets/MulticastExample.cs":::

[!code-csharp[csProgGuideDelegates#11](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideDelegates/CS/Delegates.cs#11)]

## See also

- <xref:System.MulticastDelegate>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,76 +1,41 @@
---
title: "How to declare, instantiate, and use a delegate"
description: Learn how to declare, instantiate, and use a delegate. See examples that cover C# 1.0, 2.0, and 3.0 and later.
description: Learn how to declare, instantiate, and use a delegate. This article provides several examples of declaring, instantiating, and invoking delegates.
ms.topic: how-to
ms.date: 07/20/2015
ms.date: 12/20/2024
helpviewer_keywords:
- "delegates [C#], declaring and instantiating"
ms.assetid: 61c4895f-f785-48f8-8bfe-db73b411c4ae
---
# How to declare, instantiate, and use a Delegate (C# Programming Guide)

You can declare delegates using any of the following methods:

- Declare a delegate type and declare a method with a matching signature:
[!code-csharp[csProgGuideDelegates#13](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideDelegates/CS/Delegates.cs#13)]
[!code-csharp[csProgGuideDelegates#14](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideDelegates/CS/Delegates.cs#14)]

:::code language="csharp" source="./snippets/HowToDeclareAndUse.cs" id="DeclareNamedDelegate":::

:::code language="csharp" source="./snippets/HowToDeclareAndUse.cs" id="CreateNamedInstance":::

- Assign a method group to a delegate type:
[!code-csharp[csProgGuideDelegates#32](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideDelegates/CS/Delegates.cs#32)]
- Declare an anonymous method:
[!code-csharp[csProgGuideDelegates#15](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideDelegates/CS/Delegates.cs#15)]

:::code language="csharp" source="./snippets/HowToDeclareAndUse.cs" id="MethodGroup":::

- Declare an anonymous method

:::code language="csharp" source="./snippets/HowToDeclareAndUse.cs" id="AnonymousMethod":::

- Use a lambda expression:

[!code-csharp[csProgGuideDelegates#31](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideDelegates/CS/Delegates.cs#31)]

For more information, see [Lambda Expressions](../../language-reference/operators/lambda-expressions.md).

The following example illustrates declaring, instantiating, and using a delegate. The `BookDB` class encapsulates a bookstore database that maintains a database of books. It exposes a method, `ProcessPaperbackBooks`, which finds all paperback books in the database and calls a delegate for each one. The `delegate` type that is used is named `ProcessBookCallback`. The `Test` class uses this class to print the titles and average price of the paperback books.

The use of delegates promotes good separation of functionality between the bookstore database and the client code. The client code has no knowledge of how the books are stored or how the bookstore code finds paperback books. The bookstore code has no knowledge of what processing is performed on the paperback books after it finds them.

## Example

[!code-csharp[csProgGuideDelegates#12](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideDelegates/CS/Delegates.cs#12)]

## Robust Programming

- Declaring a delegate.

The following statement declares a new delegate type.

[!code-csharp[csProgGuideDelegates#16](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideDelegates/CS/Delegates.cs#16)]

Each delegate type describes the number and types of the arguments, and the type of the return value of methods that it can encapsulate. Whenever a new set of argument types or return value type is needed, a new delegate type must be declared.

- Instantiating a delegate.

After a delegate type has been declared, a delegate object must be created and associated with a particular method. In the previous example, you do this by passing the `PrintTitle` method to the `ProcessPaperbackBooks` method as in the following example:

[!code-csharp[csProgGuideDelegates#17](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideDelegates/CS/Delegates.cs#17)]

This creates a new delegate object associated with the [static](../../language-reference/keywords/static.md) method `Test.PrintTitle`. Similarly, the non-static method `AddBookToTotal` on the object `totaller` is passed as in the following example:

[!code-csharp[csProgGuideDelegates#18](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideDelegates/CS/Delegates.cs#18)]

In both cases a new delegate object is passed to the `ProcessPaperbackBooks` method.

After a delegate is created, the method it is associated with never changes; delegate objects are immutable.

- Calling a delegate.

After a delegate object is created, the delegate object is typically passed to other code that will call the delegate. A delegate object is called by using the name of the delegate object, followed by the parenthesized arguments to be passed to the delegate. Following is an example of a delegate call:

[!code-csharp[csProgGuideDelegates#19](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideDelegates/CS/Delegates.cs#19)]

A delegate can be either called synchronously, as in this example, or asynchronously by using `BeginInvoke` and `EndInvoke` methods.


:::code language="csharp" source="./snippets/HowToDeclareAndUse.cs" id="LambdaExpression":::

For more information, see [Lambda Expressions](../../language-reference/operators/lambda-expressions.md).

The following example illustrates declaring, instantiating, and using a delegate. The `BookDB` class encapsulates a bookstore database that maintains a database of books. It exposes a method, `ProcessPaperbackBooks`, which finds all paperback books in the database and calls a delegate for each one. The `delegate` type is named `ProcessBookCallback`. The `Test` class uses this class to print the titles and average price of the paperback books.

The use of delegates promotes good separation of functionality between the bookstore database and the client code. The client code has no knowledge of how the books are stored or how the bookstore code finds paperback books. The bookstore code has no knowledge of what processing is performed on the paperback books after it finds them.

:::code language="csharp" source="./snippets/BookStore.cs":::

## See also

- [Events](../events/index.md)
Expand Down
6 changes: 2 additions & 4 deletions docs/csharp/programming-guide/delegates/index.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
---
title: "Delegates"
description: A delegate in C# is a type that refers to methods with a parameter list and return type. Delegates are used to pass methods as arguments to other methods.
ms.date: 02/02/2021
ms.date: 12/20/2024
helpviewer_keywords:
- "C# language, delegates"
- "delegates [C#]"
ms.assetid: 97de039b-c76b-4b9c-a27d-8c1e1c8d93da
---
# Delegates (C# Programming Guide)

A [delegate](../../language-reference/builtin-types/reference-types.md) is a type that represents references to methods with a particular parameter list and return type. When you instantiate a delegate, you can associate its instance with any method with a compatible signature and return type. You can invoke (or call) the method through the delegate instance.

Delegates are used to pass methods as arguments to other methods. Event handlers are nothing more than methods that are invoked through delegates. You create a custom method, and a class such as a windows control can call your method when a certain event occurs. The following example shows a delegate declaration:

[!code-csharp[csProgGuideDelegates#20](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csProgGuideDelegates/CS/Delegates.cs#20)]
:::code language="csharp" source="./snippets/Overview.cs" id="DelegateDeclaration":::

Any method from any accessible class or struct that matches the delegate type can be assigned to the delegate. The method can be either static or an instance method. This flexibility means you can programmatically change method calls, or plug new code into existing classes.

Expand All @@ -28,7 +27,6 @@ This ability to refer to a method as a parameter makes delegates ideal for defin

Delegates have the following properties:

- Delegates are similar to C++ function pointers, but delegates are fully object-oriented, and unlike C++ pointers to member functions, delegates encapsulate both an object instance and a method.
- Delegates allow methods to be passed as parameters.
- Delegates can be used to define callback methods.
- Delegates can be chained together; for example, multiple methods can be called on a single event.
Expand Down
Loading

0 comments on commit 6d25c7b

Please sign in to comment.