September 19, 2025

Photo Credit: Dall-E by OpenAI
When I tried building some code in the Visual Studio 2026 Insiders build, something strange happened:
perfectly valid code in VS 2022 started failing.
After digging in, I realized it wasn’t a bug in my code — it was a change in compiler overload resolution.
The LINQ vs Span Problem
Consider this code:
var endPart = request.SearchTerm.Split(" ")
.Reverse()
.FirstOrDefault();✅ In Visual Studio 2022
Split()returnsstring[]..Reverse()resolves toEnumerable.Reverse(IEnumerable<T>), which returns IEnumerable<T>..FirstOrDefault()works.
❌ In Visual Studio 2026 Insiders
string[]is implicitly convertible toSpan<string>..Reverse()resolves toMemoryExtensions.Reverse(Span<T>), which returns void (in-place)..FirstOrDefault()fails to compile.
Fix 1 – Be Explicit with LINQ
Force the LINQ overload:
var endPart = request.SearchTerm
.Split(' ')
.AsEnumerable()
.Reverse()
.FirstOrDefault();Fix 2 – Use LastOrDefault
Since I just needed the last token, this is cleaner:
var parts = request.SearchTerm
.Split(' ', StringSplitOptions.RemoveEmptyEntries);
var endPart = parts.LastOrDefault();RedisValue Case
Another place that broke:
return JsonSerializer
.Deserialize<RgsMapLineModel>(result);In VS 2022, it compiled fine.
But in Insiders, result is a RedisValue (struct), not directly supported by JsonSerializer.
✅ Fix:
return JsonSerializer
.Deserialize<RgsMapLineModel>(result
.ToString());Lessons Learned
- Implicit conversions to Span are picked up eagerly in the new compiler.
- Be explicit with
.AsEnumerable()or useEnumerable.Reverse()if you want LINQ. - For structs like
RedisValue, always convert before passing to APIs likeJsonSerializer.
Closing Thoughts
While this feels like a breaking change, it’s actually the compiler preferring high-performance APIs (Span<T>). That’s good for performance, but it means our code needs to be explicit about intent.
If you’re experimenting with VS Insiders, watch out for these tweaks!
A good read : Understanding C# overload-resolution
Last Note
Why does the compiler prefer Span<T>?
You might wonder why the new compiler prefers Span<T> overloads over string[] and LINQ.
The reason is performance: Span<T> lets you work with slices of arrays and strings without extra allocations.
Advantages of Span<T>
- No extra memory allocations → avoids creating new arrays when slicing strings.
- Safer than pointers → provides bounds checking while working with memory directly.
- Faster iteration → direct access without LINQ’s deferred execution overhead.
Example
// Traditional LINQ
var words = text.Split(' ');
var last = words.LastOrDefault();
// With Span<T>
ReadOnlySpan<char> span = text.AsSpan();
int idx = span.LastIndexOf(' ');
var lastWord = idx >= 0 ? span.Slice(idx + 1).ToString() : text;The second approach avoids creating an intermediate string[] entirely.
👉 I’ll explore the power of Span<T> in depth (and when not to use it) in a follow-up blog.
Peace... 🍀