-
Notifications
You must be signed in to change notification settings - Fork 5.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Breaking change]: C# overload resolution prefers span overloads which might not work in Expression lambdas #43952
Comments
Adding myself as an assignee here. I need to publish https://github.com/dotnet/roslyn/blob/main/docs/compilers/CSharp/Compiler%20Breaking%20Changes%20-%20DotNet%2010.md, which includes this compiler change. @jjonescz Are there associated library changes as well? |
No, but I was told to file this breaking change issue in dotnet/runtime#109757 (comment) Note also that the compiler breaking change doc does not describe the break in Expression trees, although the cause is the same and so those docs could be unified I imagine. |
With Native AOT and potentially other targets that do not support compilation, this fails at runtime even with |
This is basically a dead end when using classic "EF6" together with latest dotnet/c#. If you want to continue using the latest dotnet with latest lang versions with EF6, you are stuck at C#13. (Unless the EfCore Team implements a similar workaround for EF6 too). |
Not sure what you mean by "dead end". You should be always able to work around this break by casting the array to IEnumerable, or calling Enumerable.Contains as static method, etc. |
@jjonescz Yes the But yeah, there is a workaround. |
There might be an analyzer / code fixer written for this. But we are also considering a language change to avoid the break. (The "first-class spans" feature that introduced this is still in preview after all.) |
Description
C# 14 introduces new built-in span conversions and type inference rules making overloads with span parameters applicable in more scenarios.
However, Expression lambdas cannot be interpreted when they involve ref structs like Span and ReadOnlySpan. For example:
The
array.Contains
binds toEnumerable.Contains
in C# 13 but binds toMemoryExtensions.Contains
in C# 14. The latter involves ReadOnlySpan and hence crashes whenExpression.Compile(preferInterpretation: true)
is called.Version
.NET 10 Preview 1
Previous behavior
In C# 13 and earlier, an extension method taking a
ReadOnlySpan<T>
orSpan<T>
receiver is not applicable to a value of typeT[]
. Therefore, only non-span extension methods like the ones from theSystem.Linq.Enumerable
class are usually bound inside Expression lambdas.New behavior
In C# 14 and later, methods with
ReadOnlySpan<T>
orSpan<T>
parameters can participate in type inference or be used as extension methods in more scenarios. This makes span-based methods like the ones from theSystem.MemoryExtensions
class bind in more scenarios, including inside Expression lambdas where they will cause runtime exceptions when compiled with interpretation.Type of breaking change
Reason for change
The C# language feature allows simplified API design and usage (e.g., one ReadOnlySpan extension method can apply to both spans and arrays).
Recommended action
If you need to continue using Expression interpretation, you should make sure the non-span overloads are bound, e.g., by casting arguments to the exact types the method signature takes or calling the extension methods as explicit static invocations:
Feature area
Other (please put exact area in description textbox)
Affected APIs
The text was updated successfully, but these errors were encountered: