Skip to content

Commit fabb271

Browse files
BillWagnergewarrenKathleenDollarddrewnoakes
authored
Add support for nameof for open generic types, first class span implicit conversions, and implicit lambda parameters with modifiers (#44641)
* Add support for `nameof` and open generic types Fixes #44182 Add that `nameof` now supports open generic types. This is the first C# 14 feature I've added, so create the C# 14 file, and update the language version tables accordingly. * Some edits. * update to .NET 10 Get this ready for the first preview * Add first class span types Add updates to C# 14 for the First class Span types. * fix warnings * Apply suggestions from code review Co-authored-by: Genevieve Warren <[email protected]> * Update docs/csharp/whats-new/csharp-14.md Co-authored-by: Genevieve Warren <[email protected]> * Add docs updates for simpler lambda parameter modifiers Fixes #44887 Publish the speclet and update the language reference to allow modifiers on implicitly typed lambda expressions. * Apply suggestions from code review Co-authored-by: Kathleen Dollard <[email protected]> * Respond to feedback. * Update docs/csharp/whats-new/csharp-14.md * update all dates * fix build warning. * file naming. * Apply suggestions from code review Co-authored-by: Drew Noakes <[email protected]> * respond to feedback. * Remove unused snippets. * fix a build warning * a couple tweaks. Clarify the language on the field keyword. * wait on docker CI container --------- Co-authored-by: Genevieve Warren <[email protected]> Co-authored-by: Kathleen Dollard <[email protected]> Co-authored-by: Drew Noakes <[email protected]>
1 parent 7ac6349 commit fabb271

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+303
-518
lines changed

.openpublishing.redirection.csharp.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -778,7 +778,7 @@
778778
},
779779
{
780780
"source_path_from_root": "/docs/csharp/language-reference/keywords/as.md",
781-
"redirect_url": "/dotnet/csharp/language-reference/operators/type-testing-and-cast#as-operator"
781+
"redirect_url": "/dotnet/csharp/language-reference/operators/type-testing-and-cast#the-as-operator"
782782
},
783783
{
784784
"source_path_from_root": "/docs/csharp/language-reference/keywords/await.md",
@@ -1075,7 +1075,7 @@
10751075
},
10761076
{
10771077
"source_path_from_root": "/docs/csharp/language-reference/keywords/typeof.md",
1078-
"redirect_url": "/dotnet/csharp/language-reference/operators/type-testing-and-cast#typeof-operator"
1078+
"redirect_url": "/dotnet/csharp/language-reference/operators/type-testing-and-cast#the-typeof-operator"
10791079
},
10801080
{
10811081
"source_path_from_root": "/docs/csharp/language-reference/keywords/types.md",
@@ -4282,7 +4282,7 @@
42824282
},
42834283
{
42844284
"source_path_from_root": "/docs/csharp/whats-new.md",
4285-
"redirect_url": "/dotnet/csharp/whats-new/csharp-13",
4285+
"redirect_url": "/dotnet/csharp/whats-new/csharp-14",
42864286
"redirect_document_id": true
42874287
},
42884288
{

docfx.json

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,10 @@
5454
"csharp-11.0/*.md",
5555
"csharp-12.0/*.md",
5656
"csharp-13.0/*.md",
57-
"field-keyword.md"
57+
"field-keyword.md",
58+
"unbound-generic-types-in-nameof.md",
59+
"first-class-span-types.md",
60+
"simple-lambda-parameters-with-modifiers.md"
5861
],
5962
"src": "_csharplang/proposals",
6063
"dest": "csharp/language-reference/proposals",
@@ -505,7 +508,7 @@
505508
"_csharplang/proposals/csharp-11.0/*.md": "09/30/2022",
506509
"_csharplang/proposals/csharp-12.0/*.md": "08/15/2023",
507510
"_csharplang/proposals/csharp-13.0/*.md": "10/31/2024",
508-
"_csharplang/proposals/*.md": "10/31/2024",
511+
"_csharplang/proposals/*.md": "02/14/2025",
509512
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md": "11/08/2022",
510513
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 8.md": "11/08/2023",
511514
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 9.md": "11/09/2024",
@@ -681,6 +684,9 @@
681684
"_csharplang/proposals/csharp-13.0/partial-properties.md": "All partial properties and indexers",
682685
"_csharplang/proposals/csharp-13.0/overload-resolution-priority.md": "Overload resolution priority tiebreaker attribute",
683686
"_csharplang/proposals/field-keyword.md": "The `field` contextual keyword",
687+
"_csharplang/proposals/unbound-generic-types-in-nameof.md": "Unbound generic types in `nameof`",
688+
"_csharplang/proposals/first-class-span-types.md": "First-class span types",
689+
"_csharplang/proposals/simple-lambda-parameters-with-modifiers.md": "Simple lambda parameters with modifiers",
684690
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md": "C# compiler breaking changes since C# 10",
685691
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 8.md": "C# compiler breaking changes since C# 11",
686692
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 9.md": "C# compiler breaking changes since C# 12",
@@ -802,6 +808,9 @@
802808
"_csharplang/proposals/csharp-13.0/partial-properties.md": "This proposal provides for partial properties and indexers, allowing the definition of a property or indexer to be split across multiple parts.",
803809
"_csharplang/proposals/csharp-13.0/overload-resolution-priority.md": "This proposal introduces a new attribute, `OverloadResolutionPriorityAttribute`, that can be applied to methods to influence overload resolution.",
804810
"_csharplang/proposals/field-keyword.md": "This proposal introduces a new keyword, `field`, that accesses the compiler generated backing field in a property accessor.",
811+
"_csharplang/proposals/unbound-generic-types-in-nameof.md": "This proposal introduces the ability to use unbound generic types such as `List<>` in `nameof` expressions. The type argument isn't required.",
812+
"_csharplang/proposals/first-class-span-types.md": "This proposal provides several implicit conversions to `Span<T>` and `ReadOnlySpan<T>` that enable library authors to have fewer overloads and developers to write code that resolves to faster Span based APIs",
813+
"_csharplang/proposals/simple-lambda-parameters-with-modifiers.md": "This proposal provides allows lambda parmaeters to be declared with modifiers without requiring their type names. You can add modifiers like `ref` and `out` to lambda parameters without specifying their type.",
805814
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md": "Learn about any breaking changes since the initial release of C# 10 and included in C# 11",
806815
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 8.md": "Learn about any breaking changes since the initial release of C# 11 and included in C# 12",
807816
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 9.md": "Learn about any breaking changes since the initial release of C# 12 and included in C# 13",

docs/csharp/fundamentals/tutorials/safely-cast-using-pattern-matching-is-and-as-operators.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ helpviewer_keywords:
99
---
1010
# How to safely cast by using pattern matching and the is and as operators
1111

12-
Because objects are polymorphic, it's possible for a variable of a base class type to hold a derived [type](../types/index.md). To access the derived type's instance members, it's necessary to [cast](../../programming-guide/types/casting-and-type-conversions.md) the value back to the derived type. However, a cast creates the risk of throwing an <xref:System.InvalidCastException>. C# provides [pattern matching](../functional/pattern-matching.md) statements that perform a cast conditionally only when it will succeed. C# also provides the [is](../../language-reference/operators/type-testing-and-cast.md#is-operator) and [as](../../language-reference/operators/type-testing-and-cast.md#as-operator) operators to test if a value is of a certain type.
12+
Because objects are polymorphic, it's possible for a variable of a base class type to hold a derived [type](../types/index.md). To access the derived type's instance members, it's necessary to [cast](../../programming-guide/types/casting-and-type-conversions.md) the value back to the derived type. However, a cast creates the risk of throwing an <xref:System.InvalidCastException>. C# provides [pattern matching](../functional/pattern-matching.md) statements that perform a cast conditionally only when it will succeed. C# also provides the [is](../../language-reference/operators/type-testing-and-cast.md#the-is-operator) and [as](../../language-reference/operators/type-testing-and-cast.md#the-as-operator) operators to test if a value is of a certain type.
1313

1414
The following example shows how to use the pattern matching `is` statement:
1515

1616
:::code language="csharp" source="./snippets/safelycast/patternmatching/Program.cs" ID="PatternMatchingIs":::
1717

18-
The preceding sample demonstrates a few features of pattern matching syntax. The `if (a is Mammal m)` statement combines the test with an initialization assignment. The assignment occurs only when the test succeeds. The variable `m` is only in scope in the embedded `if` statement where it has been assigned. You can't access `m` later in the same method. The preceding example also shows how to use the [`as` operator](../../language-reference/operators/type-testing-and-cast.md#as-operator) to convert an object to a specified type.
18+
The preceding sample demonstrates a few features of pattern matching syntax. The `if (a is Mammal m)` statement combines the test with an initialization assignment. The assignment occurs only when the test succeeds. The variable `m` is only in scope in the embedded `if` statement where it has been assigned. You can't access `m` later in the same method. The preceding example also shows how to use the [`as` operator](../../language-reference/operators/type-testing-and-cast.md#the-as-operator) to convert an object to a specified type.
1919

2020
You can also use the same syntax for testing if a [nullable value type](../../language-reference/builtin-types/nullable-value-types.md) has a value, as shown in the following example:
2121

docs/csharp/index.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ highlightedContent:
3232
# Card
3333
- title: What's new
3434
itemType: whats-new
35-
url: ./whats-new/csharp-13.md
35+
url: ./whats-new/csharp-14.md
3636
# Card
3737
- title: Learn C# video series
3838
itemType: video

docs/csharp/language-reference/builtin-types/built-in-types.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: "Built-in types"
33
description: "Learn C# built-in value and reference types"
4-
ms.date: 03/15/2021
4+
ms.date: 02/19/2025
55
helpviewer_keywords:
66
- "types [C#], built-in"
77
- "built-in C# types"
@@ -36,7 +36,7 @@ The following table lists the C# built-in [reference](../keywords/reference-type
3636
|[`string`](reference-types.md#the-string-type)|<xref:System.String?displayProperty=nameWithType>|
3737
|[`dynamic`](reference-types.md#the-dynamic-type)|<xref:System.Object?displayProperty=nameWithType>|
3838

39-
In the preceding tables, each C# type keyword from the left column (except [dynamic](reference-types.md#the-dynamic-type)) is an alias for the corresponding .NET type. They are interchangeable. For example, the following declarations declare variables of the same type:
39+
In the preceding tables, each C# type keyword from the left column (except [dynamic](reference-types.md#the-dynamic-type)) is an alias for the corresponding .NET type. They're interchangeable. For example, the following declarations declare variables of the same type:
4040

4141
```csharp
4242
int a = 123;
@@ -45,6 +45,16 @@ System.Int32 b = 123;
4545

4646
The [`void`](void.md) keyword represents the absence of a type. You use it as the return type of a method that doesn't return a value.
4747

48+
The C# language includes specialized rules for the <xref:System.Span`1?displayProperty=fullName> and <xref:System.ReadOnlySpan`1?displayProperty=fullName> types. These types aren't classified as built-in types, because there aren't C# keywords that correspond to these types. The C# language defines implicit conversions from array types and the string type to `Span<T>` and `ReadOnlySpan<T>`. These conversions integrate `Span` types into more natural programming scenarios. The following conversions are defined as *implicit span conversions*:
49+
50+
- From any single-dimensional array with element type `E` to `System.Span<E>`
51+
- From any single-dimensional array with element type `E` to `System.ReadOnlySpan<U>`, when `E` has covariance conversion or an identity conversion to `U`
52+
- From `System.Span<E>` to `System.ReadOnlySpan<U>`, when `E` has a covariance conversion or an identity conversion to `U`
53+
- From `System.ReadOnlySpan<E>` to `System.ReadOnlySpan<U>`, when `E` has a covariance conversion or an identity conversion to `U`
54+
- From `string` to `System.ReadOnlySpan<char>`
55+
56+
The compiler never ignores any user defined conversion where an applicable *implicit span conversion* exists. Implicit span conversions can be applied to the first argument of [extension methods](../../programming-guide/classes-and-structs/extension-methods.md), the parameter with the `this` modifier. Implicit span conversions aren't considered for method group conversions.
57+
4858
## See also
4959

5060
- [Use language keywords instead of framework type names (style rule IDE0049)](../../../fundamentals/code-analysis/style-rules/ide0049.md)

docs/csharp/language-reference/builtin-types/collections.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
---
22
title: "Collections"
33
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.
4-
ms.date: 08/22/2023
4+
ms.date: 02/04/2025
55
---
66
# Collections
77

8-
The .NET runtime provides many collection types that store and manage groups of related objects. Some of the collection types, such as <xref:System.Array?displayProperty=nameWithType>, <xref:System.Span%601?displayProperty=nameWithType>, and <xref:System.Memory%601?displayProperty=nameWithType> are recognized in the C# language. In addition, interfaces like <xref:System.Collections.Generic.IEnumerable%601?displayProperty=nameWithType> are recognized in the language for enumerating the elements of a collection.
8+
The .NET runtime provides many collection types that store and manage groups of related objects. Some of the collection types, such as <xref:System.Array?displayProperty=nameWithType>, <xref:System.Span%601?displayProperty=nameWithType>, and <xref:System.Memory%601?displayProperty=nameWithType> are recognized [in the C# language](./built-in-types.md). In addition, interfaces like <xref:System.Collections.Generic.IEnumerable%601?displayProperty=nameWithType> are recognized in the language for enumerating the elements of a collection.
99

1010
Collections provide a flexible way to work with groups of objects. You can classify different collections by these characteristics:
1111

docs/csharp/language-reference/builtin-types/nullable-value-types.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,17 +96,17 @@ The following example shows how to determine whether a <xref:System.Type?display
9696

9797
[!code-csharp-interactive[whether Type is nullable](snippets/shared/NullableValueTypes.cs#IsTypeNullable)]
9898

99-
As the example shows, you use the [typeof](../operators/type-testing-and-cast.md#typeof-operator) operator to create a <xref:System.Type?displayProperty=nameWithType> instance.
99+
As the example shows, you use the [typeof](../operators/type-testing-and-cast.md#the-typeof-operator) operator to create a <xref:System.Type?displayProperty=nameWithType> instance.
100100

101101
If you want to determine whether an instance is of a nullable value type, don't use the <xref:System.Object.GetType%2A?displayProperty=nameWithType> method to get a <xref:System.Type> instance to be tested with the preceding code. When you call the <xref:System.Object.GetType%2A?displayProperty=nameWithType> method on an instance of a nullable value type, the instance is [boxed](#boxing-and-unboxing) to <xref:System.Object>. As boxing of a non-null instance of a nullable value type is equivalent to boxing of a value of the underlying type, <xref:System.Object.GetType%2A> returns a <xref:System.Type> instance that represents the underlying type of a nullable value type:
102102

103103
[!code-csharp-interactive[GetType example](snippets/shared/NullableValueTypes.cs#GetType)]
104104

105-
Also, don't use the [is](../operators/type-testing-and-cast.md#is-operator) operator to determine whether an instance is of a nullable value type. As the following example shows, you cannot distinguish types of a nullable value type instance and its underlying type instance with the `is` operator:
105+
Also, don't use the [is](../operators/type-testing-and-cast.md#the-is-operator) operator to determine whether an instance is of a nullable value type. As the following example shows, you cannot distinguish types of a nullable value type instance and its underlying type instance with the `is` operator:
106106

107107
[!code-csharp-interactive[is operator example](snippets/shared/NullableValueTypes.cs#IsOperator)]
108108

109-
Instead use the <xref:System.Nullable.GetUnderlyingType%2A?displayProperty=nameWithType> from the first example and [typeof](../operators/type-testing-and-cast.md#typeof-operator) operator to check if an instance is of a nullable value type.
109+
Instead use the <xref:System.Nullable.GetUnderlyingType%2A?displayProperty=nameWithType> from the first example and [typeof](../operators/type-testing-and-cast.md#the-typeof-operator) operator to check if an instance is of a nullable value type.
110110

111111
> [!NOTE]
112112
> The methods described in this section are not applicable in the case of [nullable reference types](nullable-reference-types.md).

docs/csharp/language-reference/compiler-messages/assembly-references.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ These compiler errors indicate one of these problems in your code:
8181

8282
- The project doesn't reference the required assembly. To fix this error, [add a reference to the required assembly](../../../standard/assembly/index.md#add-a-reference-to-an-assembly).
8383
- You misspelled the name of a type. Check the name of the type.
84-
- You used a variable name where the name of a <xref:System.Type?displayProperty=nameWithType> was expected, such as in the [`typeof` operator](../operators/type-testing-and-cast.md#typeof-operator) or the [`is` operator](../operators/type-testing-and-cast.md#is-operator).
84+
- You used a variable name where the name of a <xref:System.Type?displayProperty=nameWithType> was expected, such as in the [`typeof` operator](../operators/type-testing-and-cast.md#the-typeof-operator) or the [`is` operator](../operators/type-testing-and-cast.md#the-is-operator).
8585
- You used the [global scope operator, (`::`)](../operators/namespace-alias-qualifier.md) when the type isn't in the global namespace.
8686

8787
## Type forwarding

docs/csharp/language-reference/compiler-messages/cs0039.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ ms.assetid: f9fcb1c5-4ea4-41f3-826e-9ab0ac43dd3e
1212

1313
Cannot convert type 'type1' to 'type2' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion
1414

15-
A conversion with the [as](../operators/type-testing-and-cast.md#as-operator) operator is allowed by inheritance, reference conversions, and boxing conversions.
15+
A conversion with the [as](../operators/type-testing-and-cast.md#the-as-operator) operator is allowed by inheritance, reference conversions, and boxing conversions.
1616

1717
## Example
1818

docs/csharp/language-reference/compiler-messages/cs0413.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ ms.assetid: a01bd1ec-015b-433b-be55-b91db268d6a5
1212

1313
The type parameter 'type parameter' cannot be used with the 'as' operator because it does not have a class type constraint nor a 'class' constraint
1414

15-
This error occurs if a generic type uses the [as](../operators/type-testing-and-cast.md#as-operator) operator, but that generic type does not have a class type constraint. The `as` operator is only allowed with reference and nullable value types, so the type parameter must be constrained to guarantee that it is not a value type. To avoid this error, use a class type constraint or a reference type constraint.
15+
This error occurs if a generic type uses the [as](../operators/type-testing-and-cast.md#the-as-operator) operator, but that generic type does not have a class type constraint. The `as` operator is only allowed with reference and nullable value types, so the type parameter must be constrained to guarantee that it is not a value type. To avoid this error, use a class type constraint or a reference type constraint.
1616

1717
This is because the `as` operator could return `null`, which is not a possible value for a value type, and the type parameter must be treated as a value type unless it is a class type constraint or a reference type constraint.
1818

docs/csharp/language-reference/compiler-messages/nullable-warnings.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ The `?` is a hint to the compiler on the expectation for null values.
236236
The `!` annotation on an expression indicates that you know the expression is safe and should be assumed to be not null.
237237

238238
- You must use these annotations, not the <xref:System.Runtime.CompilerServices.NullableAttribute?displayProperty=nameWithType> in your code.
239-
- Because the `?` is an annotation, not a type, you can't use it with [`typeof`](../operators/type-testing-and-cast.md#typeof-operator), or [`new`](../operators/new-operator.md) expressions.
239+
- Because the `?` is an annotation, not a type, you can't use it with [`typeof`](../operators/type-testing-and-cast.md#the-typeof-operator), or [`new`](../operators/new-operator.md) expressions.
240240
- The `!` operator can't be applied to a variable expression or a method group.
241241
- The `!` operator can't be applied to the left of a member access operator, such as `obj.Field!.Method()`.
242242

0 commit comments

Comments
 (0)