
Now that .NET 10 and C# 14 are out lots of people are finally realising that C# 14 and .NET has broken them - and quite badly.
Basically the compiler team decided that new in-memory performance methods should take precedence over existing extension methods including common ones like Reverse (now in-place) and Contains (converts to ReadOnlySpan which doesn't work in an expression tree) and LINQ users be damned.
This is quite ironic given the C# team have said for years we can't have new syntax in expression trees as it would break old providers but here they are breaking them anyway chasing micro optimisations that have minimal impact on their core customer base.
So, you've switched to C# 14 and tried to compile, you might get a bunch of errors. The recommended solution by Microsoft is to go replace all the extension methods with calls directly to the Enumerable static class and in some cases that's your only option but it's a painful one.
Reverse
If you were using something like:
var x = source.Select(x => x.Tags.Reverse());
You will now get a compile-time error apparently when only targetting
Cannot assign
voidto an implicitly typed variable.
or
Cannot convert source type
voidto target type 'string'
The workaround here is limited to only calling the static extension:
var x = source.Select(x => Enumerable.Reverse(x.Tags));
This should work with all existing LINQ providers as that's what the compiler was doing previously anyway.
Contains
Contains breaks in a different way as a runtime error as now arrays now automatically cast to ReadOnlySpan<T> so the compiler targets the Contains in MemoryExtensions. IQueryable LINQ providers do not support this.
var x = source.Where(x => x.Tags.Contains("bad-ux"));
Your options here are:
- Wait for your LINQ provider to workaround it by rewriting the tree (EF Core 8 & 9, and MongoDB C# Driver 3.5.1 do - EF6 possibly never will)
- Rewrite the expression to use the
Enumerablestatic class directly - Write your own pre-processor to rewrite the tree (see the EF Core one for guidance)
If I find more - there probably are given the scope of this change - I'll add them here as the official breaking guidance is vague at best.
0 responses