Skip to content

Fix List<T> to ListView<T> casting bug on .NET Framework#110

Open
prozolic wants to merge 1 commit intoCysharp:masterfrom
prozolic:pullreq
Open

Fix List<T> to ListView<T> casting bug on .NET Framework#110
prozolic wants to merge 1 commit intoCysharp:masterfrom
prozolic:pullreq

Conversation

@prozolic
Copy link
Contributor

@prozolic prozolic commented Oct 22, 2025

Summary

This PR fixes a bug that occurs only in .NET Framework.

  • Sample Code
ObservableList<int> list = new ObservableList<int> { 1, 2, 3, 4, 5 };
var view = list.CreateView(x => x);
list.AddRange(new int[] { 1, 2, 3, 4, 5, 6, 7, 8 });
ObservableList<int> list = new ObservableList<int> { 1, 2, 3, 4, 5 };
list.RemoveRange(1, 3);
list.ForEach(x => Console.Write(x + ","));

The root cause is that List<T> in .NET Framework has a _syncRoot field, but ListView<T> does not include it. As a result, ListView<T>._size is not set correctly. I adjusted the code to use a different ListView<T>(LegacyListView<T>) that accounts for the number of private fields in List<T>, including _syncRoot.

A similar approach is used in ZLinq: https://github.com/Cysharp/ZLinq/blob/main/src/ZLinq/Internal/Polyfill/CollectionsMarshal.cs#L33-L44

Related issue

#109

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant