From 6ac702613fb5d8d4b1a086e43fb42108ec5b3903 Mon Sep 17 00:00:00 2001 From: "Darrin W. Cullop" Date: Thu, 9 Nov 2023 00:17:26 -0800 Subject: [PATCH] ToConcreteType Update (#751) Convert more places to use ToConcreteType --- .../Aggregation/AggregateEnumerator.cs | 5 +++-- src/DynamicData/Binding/BindingListAdaptor.cs | 4 ++-- .../Binding/ObservableCollectionAdaptor.cs | 20 ++----------------- src/DynamicData/Cache/CacheChangeSetEx.cs | 13 ++++++++---- .../Cache/Internal/AbstractFilter.cs | 4 ++-- src/DynamicData/Cache/Internal/Cache.cs | 2 +- src/DynamicData/Cache/Internal/Cast.cs | 2 +- src/DynamicData/Cache/Internal/Combiner.cs | 2 +- src/DynamicData/Cache/Internal/DisposeMany.cs | 2 +- .../Cache/Internal/IndexCalculator.cs | 2 +- .../Cache/Internal/RemoveKeyEnumerator.cs | 2 +- .../Cache/Internal/TransformMany.cs | 2 +- src/DynamicData/Cache/ObservableCacheEx.cs | 5 +++-- src/DynamicData/Platforms/net45/PFilter.cs | 2 +- 14 files changed, 29 insertions(+), 38 deletions(-) diff --git a/src/DynamicData/Aggregation/AggregateEnumerator.cs b/src/DynamicData/Aggregation/AggregateEnumerator.cs index 27ad8e625..7800f3346 100644 --- a/src/DynamicData/Aggregation/AggregateEnumerator.cs +++ b/src/DynamicData/Aggregation/AggregateEnumerator.cs @@ -5,6 +5,7 @@ using System.Collections; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using DynamicData.Cache; namespace DynamicData.Aggregation; @@ -68,11 +69,11 @@ internal class AggregateEnumerator : IAggregateChangeSet where TObject : notnull where TKey : notnull { - private readonly IChangeSet _source; + private readonly ChangeSet _source; public AggregateEnumerator(IChangeSet source) { - _source = source; + _source = source.ToConcreteType(); } public IEnumerator> GetEnumerator() diff --git a/src/DynamicData/Binding/BindingListAdaptor.cs b/src/DynamicData/Binding/BindingListAdaptor.cs index 5ca39454e..d11944e7b 100644 --- a/src/DynamicData/Binding/BindingListAdaptor.cs +++ b/src/DynamicData/Binding/BindingListAdaptor.cs @@ -5,7 +5,7 @@ #if SUPPORTS_BINDINGLIST using System.ComponentModel; using System.Diagnostics.CodeAnalysis; - +using DynamicData.Cache; using DynamicData.Cache.Internal; namespace DynamicData.Binding @@ -108,7 +108,7 @@ public void Adapt(IChangeSet changes) private static void DoUpdate(IChangeSet changes, BindingList list) { - foreach (var update in changes) + foreach (var update in changes.ToConcreteType()) { switch (update.Reason) { diff --git a/src/DynamicData/Binding/ObservableCollectionAdaptor.cs b/src/DynamicData/Binding/ObservableCollectionAdaptor.cs index a373be9aa..6926fa702 100644 --- a/src/DynamicData/Binding/ObservableCollectionAdaptor.cs +++ b/src/DynamicData/Binding/ObservableCollectionAdaptor.cs @@ -4,7 +4,7 @@ using System; using System.Diagnostics.CodeAnalysis; - +using DynamicData.Cache; using DynamicData.Cache.Internal; using DynamicData.Kernel; @@ -128,7 +128,7 @@ public void Adapt(IChangeSet changes, IObservableCollection changes, IObservableCollection list) { - void Amend(Change change) + foreach (Change change in changes.ToConcreteType()) { switch (change.Reason) { @@ -156,21 +156,5 @@ void Amend(Change change) break; } } - - if (changes is IList> iList) - { - // allocation free enumeration - foreach (var change in EnumerableIList.Create(iList)) - { - Amend(change); - } - } - else - { - foreach (var update in changes) - { - Amend(update); - } - } } } diff --git a/src/DynamicData/Cache/CacheChangeSetEx.cs b/src/DynamicData/Cache/CacheChangeSetEx.cs index 7ab076a0b..edbc8a825 100644 --- a/src/DynamicData/Cache/CacheChangeSetEx.cs +++ b/src/DynamicData/Cache/CacheChangeSetEx.cs @@ -9,14 +9,19 @@ internal static class CacheChangeSetEx /// /// IChangeSet is flawed because it automatically means allocations when enumerating. /// This extension is a crazy hack to cast to the concrete change set which means we no longer allocate - /// as change set now inherits from List which has allocation free enumerations. + /// as change set now inherits from List which has allocation free enumerations. /// - /// IChangeSet will be removed in V7 and instead Change sets will be used directly + /// IChangeSet will be removed in a future version and instead will be used directly. /// /// In the mean time I am banking that no-one has implemented a custom change set - personally I think it is very unlikely. /// - /// The source change set. + /// ChangeSet Object Type. + /// ChangeSet Key Type. + /// ChangeSet to be converted. + /// Concrete Instance of the ChangeSet. + /// A custom implementation was found. public static ChangeSet ToConcreteType(this IChangeSet changeSet) where TObject : notnull - where TKey : notnull => (ChangeSet)changeSet; + where TKey : notnull => + changeSet as ChangeSet ?? throw new NotSupportedException("Dynamic Data does not support a custom implementation of IChangeSet"); } diff --git a/src/DynamicData/Cache/Internal/AbstractFilter.cs b/src/DynamicData/Cache/Internal/AbstractFilter.cs index d76dabeff..34db2d95a 100644 --- a/src/DynamicData/Cache/Internal/AbstractFilter.cs +++ b/src/DynamicData/Cache/Internal/AbstractFilter.cs @@ -59,11 +59,11 @@ Optional> Factory(KeyValuePair kv) public IChangeSet Update(IChangeSet updates) { - var withFilter = GetChangesWithFilter(updates); + var withFilter = GetChangesWithFilter(updates.ToConcreteType()); return ProcessResult(withFilter); } - protected abstract IEnumerable GetChangesWithFilter(IChangeSet updates); + protected abstract IEnumerable GetChangesWithFilter(ChangeSet updates); protected abstract IEnumerable> Refresh(IEnumerable> items, Func, Optional>> factory); diff --git a/src/DynamicData/Cache/Internal/Cache.cs b/src/DynamicData/Cache/Internal/Cache.cs index d1477c793..623b28e75 100644 --- a/src/DynamicData/Cache/Internal/Cache.cs +++ b/src/DynamicData/Cache/Internal/Cache.cs @@ -47,7 +47,7 @@ public void Clone(IChangeSet changes) throw new ArgumentNullException(nameof(changes)); } - foreach (var item in changes) + foreach (var item in changes.ToConcreteType()) { switch (item.Reason) { diff --git a/src/DynamicData/Cache/Internal/Cast.cs b/src/DynamicData/Cache/Internal/Cast.cs index f006a0eba..051be77f1 100644 --- a/src/DynamicData/Cache/Internal/Cast.cs +++ b/src/DynamicData/Cache/Internal/Cast.cs @@ -30,7 +30,7 @@ public IObservable> Run() return _source.Select( changes => { - var transformed = changes.Select(change => new Change(change.Reason, change.Key, _converter(change.Current), change.Previous.Convert(_converter), change.CurrentIndex, change.PreviousIndex)); + var transformed = changes.ToConcreteType().Select(change => new Change(change.Reason, change.Key, _converter(change.Current), change.Previous.Convert(_converter), change.CurrentIndex, change.PreviousIndex)); return new ChangeSet(transformed); }); } diff --git a/src/DynamicData/Cache/Internal/Combiner.cs b/src/DynamicData/Cache/Internal/Combiner.cs index 758868282..5b9e0d648 100644 --- a/src/DynamicData/Cache/Internal/Combiner.cs +++ b/src/DynamicData/Cache/Internal/Combiner.cs @@ -106,7 +106,7 @@ private void Update(Cache cache, IChangeSet update private IChangeSet UpdateCombined(IChangeSet updates) { // child caches have been updated before we reached this point. - foreach (var update in updates) + foreach (var update in updates.ToConcreteType()) { TKey key = update.Key; switch (update.Reason) diff --git a/src/DynamicData/Cache/Internal/DisposeMany.cs b/src/DynamicData/Cache/Internal/DisposeMany.cs index 41b6e061e..2b0091c58 100644 --- a/src/DynamicData/Cache/Internal/DisposeMany.cs +++ b/src/DynamicData/Cache/Internal/DisposeMany.cs @@ -49,7 +49,7 @@ public IObservable> Run() private void RegisterForRemoval(IChangeSet changes, Cache cache) { - changes.ForEach( + changes.ToConcreteType().ForEach( change => { switch (change.Reason) diff --git a/src/DynamicData/Cache/Internal/IndexCalculator.cs b/src/DynamicData/Cache/Internal/IndexCalculator.cs index 57bbfcb50..ad42bbdd1 100644 --- a/src/DynamicData/Cache/Internal/IndexCalculator.cs +++ b/src/DynamicData/Cache/Internal/IndexCalculator.cs @@ -47,7 +47,7 @@ public IChangeSet Calculate(IChangeSet changes) var result = new List>(changes.Count); var refreshes = new List>(changes.Refreshes); - foreach (var u in changes) + foreach (var u in changes.ToConcreteType()) { var current = new KeyValuePair(u.Key, u.Current); diff --git a/src/DynamicData/Cache/Internal/RemoveKeyEnumerator.cs b/src/DynamicData/Cache/Internal/RemoveKeyEnumerator.cs index 554cd1aaa..19676413d 100644 --- a/src/DynamicData/Cache/Internal/RemoveKeyEnumerator.cs +++ b/src/DynamicData/Cache/Internal/RemoveKeyEnumerator.cs @@ -36,7 +36,7 @@ public RemoveKeyEnumerator(IChangeSet source, IExtendedList public IEnumerator> GetEnumerator() { - foreach (var change in _source) + foreach (var change in _source.ToConcreteType()) { switch (change.Reason) { diff --git a/src/DynamicData/Cache/Internal/TransformMany.cs b/src/DynamicData/Cache/Internal/TransformMany.cs index fbdcbe042..31cf4e83a 100644 --- a/src/DynamicData/Cache/Internal/TransformMany.cs +++ b/src/DynamicData/Cache/Internal/TransformMany.cs @@ -207,7 +207,7 @@ public DestinationEnumerator(IChangeSet changes) public IEnumerator> GetEnumerator() { - foreach (var change in _changes) + foreach (var change in _changes.ToConcreteType()) { switch (change.Reason) { diff --git a/src/DynamicData/Cache/ObservableCacheEx.cs b/src/DynamicData/Cache/ObservableCacheEx.cs index 11cdb311b..368f490f1 100644 --- a/src/DynamicData/Cache/ObservableCacheEx.cs +++ b/src/DynamicData/Cache/ObservableCacheEx.cs @@ -14,6 +14,7 @@ using System.Reactive.Linq; using DynamicData.Binding; +using DynamicData.Cache; using DynamicData.Cache.Internal; using DynamicData.Kernel; @@ -1058,7 +1059,7 @@ public static IObservable> Clone(this I return source.Do( changes => { - foreach (var item in changes) + foreach (var item in changes.ToConcreteType()) { switch (item.Reason) { @@ -6200,7 +6201,7 @@ public static IObservable> TreatMovesAsRemoveAdd IEnumerable> ReplaceMoves(IChangeSet items) { - foreach (var change in items) + foreach (var change in items.ToConcreteType()) { if (change.Reason == ChangeReason.Moved) { diff --git a/src/DynamicData/Platforms/net45/PFilter.cs b/src/DynamicData/Platforms/net45/PFilter.cs index c5e2eefc1..b1fec41cf 100644 --- a/src/DynamicData/Platforms/net45/PFilter.cs +++ b/src/DynamicData/Platforms/net45/PFilter.cs @@ -51,7 +51,7 @@ public PLinqFilteredUpdater(Func filter, ParallelisationOptions p _parallelisationOptions = parallelisationOptions; } - protected override IEnumerable GetChangesWithFilter(IChangeSet updates) + protected override IEnumerable GetChangesWithFilter(ChangeSet updates) { if (updates.ShouldParallelise(_parallelisationOptions)) {