diff --git a/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 10.md b/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 10.md index 657d95963527c..f1db06a885147 100644 --- a/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 10.md +++ b/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 10.md @@ -19,7 +19,7 @@ Assert.Equal([2], x); // previously Assert.Equal(T[], T[]), now ambiguous wit Assert.Equal([2], x.AsSpan()); // workaround var y = new int[] { 1, 2 }; -var s = new ArraySegment(x, 1, 1); +var s = new ArraySegment(y, 1, 1); Assert.Equal(y, s); // previously Assert.Equal(T, T), now ambiguous with Assert.Equal(Span, Span) Assert.Equal(y.AsSpan(), s); // workaround ``` @@ -39,11 +39,26 @@ static class C public static void R(IEnumerable e) => Console.Write(1); public static void R(Span s) => Console.Write(2); // another workaround: - [OverloadResolutionPriority(1)] public static void R(ReadOnlySpan s) => Console.Write(3); } ``` +For that reason, `ReadOnlySpan` is generally preferred over `Span` by overload resolution in C# 14. +In some cases, that might lead to compilation breaks, +for example when there are overloads for both `Span` and `ReadOnlySpan`, both taking and returning the same span type: + +```cs +int[] x = new[0]; +Span y = MemoryMarshal.Cast(x); // previously worked, now compilation error +Span z = MemoryMarshal.Cast(x.AsSpan()); // workaround + +static class MemoryMarshal +{ + public static ReadOnlySpan Cast(ReadOnlySpan span) => default; + public static Span Cast(Span span) => default; +} +``` + When using C# 14 or newer and targeting a .NET older than `net10.0` or .NET Framework with `System.Memory` reference, there is a breaking change with `Enumerable.Reverse` and arrays: