Skip to content
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
5 changes: 5 additions & 0 deletions docs/core/compatibility/3.1-5.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ If you're migrating from version 3.1 of .NET Core, ASP.NET Core, or EF Core to v

## Core .NET libraries

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

[!INCLUDE [lastindexof-improved-handling-of-empty-values](../../../includes/core-changes/corefx/5.0/lastindexof-improved-handling-of-empty-values.md)]

***

[!INCLUDE [globalassemblycache-property-obsolete](../../../includes/core-changes/corefx/5.0/global-assembly-cache-apis-obsolete.md)]

***
Expand Down
5 changes: 5 additions & 0 deletions docs/core/compatibility/corefx.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ The following breaking changes are documented on this page:

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

## .NET 5.0

[!INCLUDE [lastindexof-improved-handling-of-empty-values](../../../includes/core-changes/corefx/5.0/lastindexof-improved-handling-of-empty-values.md)]

***

[!INCLUDE [remoting-apis-obsolete](../../../includes/core-changes/corefx/5.0/remoting-apis-obsolete.md)]

***
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
### LastIndexOf has improved handling of empty search strings

<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.

#### Change description

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.

```csharp
Console.WriteLine("Hello".LastIndexOf("")); // prints '4' (incorrect)

ReadOnlySpan<char> span = "Hello";
Console.WriteLine(span.LastIndexOf("")); // prints '0' (incorrect)
```

Starting with .NET 5.0, these APIs return the correct value for `LastIndexOf`.

```csharp
Console.WriteLine("Hello".LastIndexOf("")); // prints '5' (correct)

ReadOnlySpan<char> span = "Hello";
Console.WriteLine(span.LastIndexOf("")); // prints '5' (correct)
```

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.

#### Reason for change

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).

#### Version introduced

5.0

#### Recommended action

You don't need to take any action. The .NET 5.0 runtime provides the new behaviors automatically.

There is no compatibility switch to restore the old behavior.

#### Category

Core .NET libraries

#### Affected APIs

- <xref:System.String.LastIndexOf%2A?displayProperty=fullName>
- <xref:System.Globalization.CompareInfo.LastIndexOf%2A?displayProperty=fullName>
- <xref:System.MemoryExtensions.LastIndexOf%2A?displayProperty=fullName>

<!--

#### Affected APIs

- `Overload:System.String.LastIndexOf`
- `Overload:System.Globalization.CompareInfo.LastIndexOf`
- `Overload:System.MemoryExtensions.LastIndexOf`

-->