Skip to content

Commit dcdb77d

Browse files
authored
LastIndexOf breaking change (#21375)
1 parent 02613a1 commit dcdb77d

File tree

3 files changed

+69
-0
lines changed

3 files changed

+69
-0
lines changed

docs/core/compatibility/3.1-5.0.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ If you're migrating from version 3.1 of .NET Core, ASP.NET Core, or EF Core to v
215215

216216
## Core .NET libraries
217217

218+
- [LastIndexOf has improved handling of empty search strings](#lastindexof-has-improved-handling-of-empty-search-strings)
218219
- [Global assembly cache APIs are obsolete](#global-assembly-cache-apis-are-obsolete)
219220
- [Remoting APIs are obsolete](#remoting-apis-are-obsolete)
220221
- [Most code access security APIs are obsolete](#most-code-access-security-apis-are-obsolete)
@@ -241,6 +242,10 @@ If you're migrating from version 3.1 of .NET Core, ASP.NET Core, or EF Core to v
241242
- [CounterSet.CreateCounterSetInstance now throws InvalidOperationException if instance already exist](#countersetcreatecountersetinstance-now-throws-invalidoperationexception-if-instance-already-exists)
242243
- [Microsoft.DotNet.PlatformAbstractions package removed](#microsoftdotnetplatformabstractions-package-removed)
243244

245+
[!INCLUDE [lastindexof-improved-handling-of-empty-values](../../../includes/core-changes/corefx/5.0/lastindexof-improved-handling-of-empty-values.md)]
246+
247+
***
248+
244249
[!INCLUDE [globalassemblycache-property-obsolete](../../../includes/core-changes/corefx/5.0/global-assembly-cache-apis-obsolete.md)]
245250

246251
***

docs/core/compatibility/corefx.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ The following breaking changes are documented on this page:
1111

1212
| Breaking change | Version introduced |
1313
| - | :-: |
14+
| [LastIndexOf has improved handling of empty search strings](#lastindexof-has-improved-handling-of-empty-search-strings) | 5.0 |
1415
| [Global assembly cache APIs are obsolete](#global-assembly-cache-apis-are-obsolete) | 5.0 |
1516
| [Remoting APIs are obsolete](#remoting-apis-are-obsolete) | 5.0 |
1617
| [Most code access security APIs are obsolete](#most-code-access-security-apis-are-obsolete) | 5.0 |
@@ -57,6 +58,10 @@ The following breaking changes are documented on this page:
5758

5859
## .NET 5.0
5960

61+
[!INCLUDE [lastindexof-improved-handling-of-empty-values](../../../includes/core-changes/corefx/5.0/lastindexof-improved-handling-of-empty-values.md)]
62+
63+
***
64+
6065
[!INCLUDE [remoting-apis-obsolete](../../../includes/core-changes/corefx/5.0/remoting-apis-obsolete.md)]
6166

6267
***
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
### LastIndexOf has improved handling of empty search strings
2+
3+
<xref:System.String.LastIndexOf%2A?displayProperty=nameWithType> and related APIs now return correct values when searching for a zero-length (or zero-length equivalent) substring within a larger string.
4+
5+
#### Change description
6+
7+
In .NET Framework and .NET Core 1.0 - 3.1, <xref:System.String.LastIndexOf%2A?displayProperty=nameWithType> and related APIs might return an incorrect value when the caller searches for a zero-length substring.
8+
9+
```csharp
10+
Console.WriteLine("Hello".LastIndexOf("")); // prints '4' (incorrect)
11+
12+
ReadOnlySpan<char> span = "Hello";
13+
Console.WriteLine(span.LastIndexOf("")); // prints '0' (incorrect)
14+
```
15+
16+
Starting with .NET 5.0, these APIs return the correct value for `LastIndexOf`.
17+
18+
```csharp
19+
Console.WriteLine("Hello".LastIndexOf("")); // prints '5' (correct)
20+
21+
ReadOnlySpan<char> span = "Hello";
22+
Console.WriteLine(span.LastIndexOf("")); // prints '5' (correct)
23+
```
24+
25+
In these examples, `5` is the correct answer because `"Hello".Substring(5)` and `"Hello".AsSpan().Slice(5)` both produce an empty string, which is trivially equal to the empty substring that is sought.
26+
27+
#### Reason for change
28+
29+
This change was part of an overall bug fixing effort around string handling for .NET 5. It also helps unify our behavior between Windows and non-Windows platforms. For more information, see [dotnet/runtime#13383](https://github.com/dotnet/runtime/issues/13383) and [dotnet/runtime##13382](https://github.com/dotnet/runtime/issues/13382).
30+
31+
#### Version introduced
32+
33+
5.0
34+
35+
#### Recommended action
36+
37+
You don't need to take any action. The .NET 5.0 runtime provides the new behaviors automatically.
38+
39+
There is no compatibility switch to restore the old behavior.
40+
41+
#### Category
42+
43+
Core .NET libraries
44+
45+
#### Affected APIs
46+
47+
- <xref:System.String.LastIndexOf%2A?displayProperty=fullName>
48+
- <xref:System.Globalization.CompareInfo.LastIndexOf%2A?displayProperty=fullName>
49+
- <xref:System.MemoryExtensions.LastIndexOf%2A?displayProperty=fullName>
50+
51+
<!--
52+
53+
#### Affected APIs
54+
55+
- `Overload:System.String.LastIndexOf`
56+
- `Overload:System.Globalization.CompareInfo.LastIndexOf`
57+
- `Overload:System.MemoryExtensions.LastIndexOf`
58+
59+
-->

0 commit comments

Comments
 (0)