From 85256010a3649b2c59000f67adf2e5b8e2eba9ae Mon Sep 17 00:00:00 2001 From: Roland Pheasant Date: Wed, 20 Mar 2024 07:40:08 +0000 Subject: [PATCH 1/3] Enable the use of default comparer for SortAndBind --- ...ts.DynamicDataTests.DotNet8_0.verified.txt | 12 ++++ .../Cache/SortAndBindFixture.cs | 30 +++++++- src/DynamicData.Tests/Domain/Person.cs | 9 ++- .../Cache/ObservableCacheEx.SortAndBind.cs | 70 ++++++++++++++++++- 4 files changed, 114 insertions(+), 7 deletions(-) diff --git a/src/DynamicData.Tests/API/ApiApprovalTests.DynamicDataTests.DotNet8_0.verified.txt b/src/DynamicData.Tests/API/ApiApprovalTests.DynamicDataTests.DotNet8_0.verified.txt index 75f432247..2fdb688aa 100644 --- a/src/DynamicData.Tests/API/ApiApprovalTests.DynamicDataTests.DotNet8_0.verified.txt +++ b/src/DynamicData.Tests/API/ApiApprovalTests.DynamicDataTests.DotNet8_0.verified.txt @@ -1760,9 +1760,21 @@ namespace DynamicData public static System.IObservable> Sort(this System.IObservable> source, System.IObservable> comparerObservable, System.IObservable resorter, DynamicData.SortOptimisations sortOptimisations = 0, int resetThreshold = 100) where TObject : notnull where TKey : notnull { } + public static System.IObservable> SortAndBind(this System.IObservable> source, System.Collections.Generic.IList targetList) + where TObject : notnull + where TKey : notnull { } + public static System.IObservable> SortAndBind(this System.IObservable> source, out System.Collections.ObjectModel.ReadOnlyObservableCollection readOnlyObservableCollection) + where TObject : notnull, System.IComparable + where TKey : notnull { } + public static System.IObservable> SortAndBind(this System.IObservable> source, System.Collections.Generic.IList targetList, DynamicData.Binding.SortAndBindOptions options) + where TObject : notnull + where TKey : notnull { } public static System.IObservable> SortAndBind(this System.IObservable> source, System.Collections.Generic.IList targetList, System.Collections.Generic.IComparer comparer) where TObject : notnull where TKey : notnull { } + public static System.IObservable> SortAndBind(this System.IObservable> source, out System.Collections.ObjectModel.ReadOnlyObservableCollection readOnlyObservableCollection, DynamicData.Binding.SortAndBindOptions options) + where TObject : notnull, System.IComparable + where TKey : notnull { } public static System.IObservable> SortAndBind(this System.IObservable> source, out System.Collections.ObjectModel.ReadOnlyObservableCollection readOnlyObservableCollection, System.Collections.Generic.IComparer comparer) where TObject : notnull where TKey : notnull { } diff --git a/src/DynamicData.Tests/Cache/SortAndBindFixture.cs b/src/DynamicData.Tests/Cache/SortAndBindFixture.cs index 140113477..723a39cd1 100644 --- a/src/DynamicData.Tests/Cache/SortAndBindFixture.cs +++ b/src/DynamicData.Tests/Cache/SortAndBindFixture.cs @@ -9,7 +9,6 @@ using DynamicData.Binding; using DynamicData.Tests.Domain; using FluentAssertions; -using Mono.Cecil; using Xunit; namespace DynamicData.Tests.Cache; @@ -28,6 +27,19 @@ protected override (ChangeSetAggregator Aggregrator, IList Aggregrator, IList List) SetUpTests() + { + var list = new List(100); + var aggregator = _source.Connect().SortAndBind(list).AsAggregator(); + + return (aggregator, list); + } +} + // Bind to an observable collection public sealed class SortAndBindToObservableCollection : SortAndBindFixture @@ -36,11 +48,11 @@ protected override (ChangeSetAggregator Aggregrator, IList(new List(100)); var aggregator = _source.Connect().SortAndBind(list, _comparer).AsAggregator(); - return (aggregator, list); } } + // Bind to a readonly observable collection public sealed class SortAndBindToReadOnlyObservableCollection: SortAndBindFixture { @@ -64,6 +76,17 @@ protected override (ChangeSetAggregator Aggregrator, IList Aggregrator, IList List) SetUpTests() + { + var aggregator = _source.Connect().SortAndBind(out var list).AsAggregator(); + + return (aggregator, list); + } +} + public sealed class SortAndBindWithResetOptions: IDisposable { @@ -144,7 +167,7 @@ public abstract class SortAndBindFixture : IDisposable private readonly ChangeSetAggregator _results; private readonly IList _boundList; - protected readonly IComparer _comparer = SortExpressionComparer.Ascending(p => p.Age).ThenByAscending(p => p.Name); + protected readonly IComparer _comparer = Person.DefaultComparer; protected readonly ISourceCache _source = new SourceCache(p => p.Key); @@ -531,3 +554,4 @@ public void Dispose() _results.Dispose(); } } + diff --git a/src/DynamicData.Tests/Domain/Person.cs b/src/DynamicData.Tests/Domain/Person.cs index 8ef805dfe..0018cbbaa 100644 --- a/src/DynamicData.Tests/Domain/Person.cs +++ b/src/DynamicData.Tests/Domain/Person.cs @@ -17,7 +17,7 @@ public enum Color Violet, } -public class Person : AbstractNotifyPropertyChanged, IEquatable +public class Person : AbstractNotifyPropertyChanged, IEquatable, IComparable { private int _age; private int? _ageNullable; @@ -215,4 +215,11 @@ public int GetHashCode(Person obj) } } } + + // Implemented for SortAndBindFixture. + public static IComparer DefaultComparer { get; } = SortExpressionComparer + .Ascending(p => p.Age) + .ThenByAscending(p => p.Name); + + public int CompareTo(Person? other) => DefaultComparer.Compare(this, other); } diff --git a/src/DynamicData/Cache/ObservableCacheEx.SortAndBind.cs b/src/DynamicData/Cache/ObservableCacheEx.SortAndBind.cs index 86eed4990..622364a2c 100644 --- a/src/DynamicData/Cache/ObservableCacheEx.SortAndBind.cs +++ b/src/DynamicData/Cache/ObservableCacheEx.SortAndBind.cs @@ -13,7 +13,39 @@ namespace DynamicData; public static partial class ObservableCacheEx { /// - /// Bind sorted data to the specified readonly observable collection. + /// Bind sorted data to the specified collection IList for an object which implements IComparable>. + /// + /// The type of the object. + /// The type of the key. + /// The source. + /// The list to bind to. + /// An observable which will emit change sets. + public static IObservable> SortAndBind( + this IObservable> source, + IList targetList) + where TObject : notnull + where TKey : notnull => + source.SortAndBind(targetList, DynamicDataOptions.SortAndBind); + + /// + /// Bind sorted data to the specified collection IList for an object which implements IComparable>. + /// + /// The type of the object. + /// The type of the key. + /// The source. + /// The list to bind to. + /// Bind and sort default options. + /// An observable which will emit change sets. + public static IObservable> SortAndBind( + this IObservable> source, + IList targetList, + SortAndBindOptions options) + where TObject : notnull + where TKey : notnull => + source.SortAndBind(targetList, Comparer.Default, options); + + /// + /// Bind sorted data to the specified collection IList. /// /// The type of the object. /// The type of the key. @@ -27,10 +59,10 @@ public static IObservable> SortAndBind( IComparer comparer) where TObject : notnull where TKey : notnull => - new SortAndBind(source, comparer, DynamicDataOptions.SortAndBind, targetList).Run(); + source.SortAndBind(targetList, comparer, DynamicDataOptions.SortAndBind); /// - /// Bind sorted data to the specified readonly observable collection. + /// Bind sorted data to the specified collection IList. /// /// The type of the object. /// The type of the key. @@ -48,6 +80,38 @@ public static IObservable> SortAndBind( where TKey : notnull => new SortAndBind(source, comparer, options, targetList).Run(); + /// + /// Bind sorted data to the specified readonly observable collection for an object which implements IComparable>. + /// + /// The type of the object. + /// The type of the key. + /// The source. + /// The resulting read only observable collection. + /// An observable which will emit change sets. + public static IObservable> SortAndBind( + this IObservable> source, + out ReadOnlyObservableCollection readOnlyObservableCollection) + where TObject : notnull, IComparable + where TKey : notnull => + source.SortAndBind(out readOnlyObservableCollection, Comparer.Default, DynamicDataOptions.SortAndBind); + + /// + /// Bind sorted data to the specified readonly observable collection for an object which implements IComparable>. + /// + /// The type of the object. + /// The type of the key. + /// The source. + /// The resulting read only observable collection. + /// Bind and sort default options. + /// An observable which will emit change sets. + public static IObservable> SortAndBind( + this IObservable> source, + out ReadOnlyObservableCollection readOnlyObservableCollection, + SortAndBindOptions options) + where TObject : notnull, IComparable + where TKey : notnull => + source.SortAndBind(out readOnlyObservableCollection, Comparer.Default, options); + /// /// Bind sorted data to the specified readonly observable collection. /// From b3fb841c9ae79298f173af950a8f66644d21104e Mon Sep 17 00:00:00 2001 From: Roland Pheasant Date: Wed, 20 Mar 2024 07:46:34 +0000 Subject: [PATCH 2/3] Enhance sort and bind comments --- src/DynamicData/Cache/ObservableCacheEx.SortAndBind.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/DynamicData/Cache/ObservableCacheEx.SortAndBind.cs b/src/DynamicData/Cache/ObservableCacheEx.SortAndBind.cs index 622364a2c..2f1bbfa78 100644 --- a/src/DynamicData/Cache/ObservableCacheEx.SortAndBind.cs +++ b/src/DynamicData/Cache/ObservableCacheEx.SortAndBind.cs @@ -13,7 +13,7 @@ namespace DynamicData; public static partial class ObservableCacheEx { /// - /// Bind sorted data to the specified collection IList for an object which implements IComparable>. + /// Bind sorted data to the specified collection, for an object which implements IComparable>. /// /// The type of the object. /// The type of the key. @@ -28,7 +28,7 @@ public static IObservable> SortAndBind( source.SortAndBind(targetList, DynamicDataOptions.SortAndBind); /// - /// Bind sorted data to the specified collection IList for an object which implements IComparable>. + /// Bind sorted data to the specified collection, for an object which implements IComparable>. /// /// The type of the object. /// The type of the key. @@ -45,7 +45,7 @@ public static IObservable> SortAndBind( source.SortAndBind(targetList, Comparer.Default, options); /// - /// Bind sorted data to the specified collection IList. + /// Bind sorted data to the specified collection. /// /// The type of the object. /// The type of the key. @@ -62,7 +62,7 @@ public static IObservable> SortAndBind( source.SortAndBind(targetList, comparer, DynamicDataOptions.SortAndBind); /// - /// Bind sorted data to the specified collection IList. + /// Bind sorted data to the specified collection. /// /// The type of the object. /// The type of the key. From 65829d61820ebce8717f19c39ee0a2112fb77bd0 Mon Sep 17 00:00:00 2001 From: Roland Pheasant Date: Wed, 20 Mar 2024 08:02:24 +0000 Subject: [PATCH 3/3] Add restrain to SortAndBind list overloads where no comparer is specified --- .../ApiApprovalTests.DynamicDataTests.DotNet8_0.verified.txt | 4 ++-- src/DynamicData/Cache/ObservableCacheEx.SortAndBind.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/DynamicData.Tests/API/ApiApprovalTests.DynamicDataTests.DotNet8_0.verified.txt b/src/DynamicData.Tests/API/ApiApprovalTests.DynamicDataTests.DotNet8_0.verified.txt index 2fdb688aa..6bb7849cc 100644 --- a/src/DynamicData.Tests/API/ApiApprovalTests.DynamicDataTests.DotNet8_0.verified.txt +++ b/src/DynamicData.Tests/API/ApiApprovalTests.DynamicDataTests.DotNet8_0.verified.txt @@ -1761,13 +1761,13 @@ namespace DynamicData where TObject : notnull where TKey : notnull { } public static System.IObservable> SortAndBind(this System.IObservable> source, System.Collections.Generic.IList targetList) - where TObject : notnull + where TObject : notnull, System.IComparable where TKey : notnull { } public static System.IObservable> SortAndBind(this System.IObservable> source, out System.Collections.ObjectModel.ReadOnlyObservableCollection readOnlyObservableCollection) where TObject : notnull, System.IComparable where TKey : notnull { } public static System.IObservable> SortAndBind(this System.IObservable> source, System.Collections.Generic.IList targetList, DynamicData.Binding.SortAndBindOptions options) - where TObject : notnull + where TObject : notnull, System.IComparable where TKey : notnull { } public static System.IObservable> SortAndBind(this System.IObservable> source, System.Collections.Generic.IList targetList, System.Collections.Generic.IComparer comparer) where TObject : notnull diff --git a/src/DynamicData/Cache/ObservableCacheEx.SortAndBind.cs b/src/DynamicData/Cache/ObservableCacheEx.SortAndBind.cs index 2f1bbfa78..27bbd6500 100644 --- a/src/DynamicData/Cache/ObservableCacheEx.SortAndBind.cs +++ b/src/DynamicData/Cache/ObservableCacheEx.SortAndBind.cs @@ -23,7 +23,7 @@ public static partial class ObservableCacheEx public static IObservable> SortAndBind( this IObservable> source, IList targetList) - where TObject : notnull + where TObject : notnull, IComparable where TKey : notnull => source.SortAndBind(targetList, DynamicDataOptions.SortAndBind); @@ -40,7 +40,7 @@ public static IObservable> SortAndBind( this IObservable> source, IList targetList, SortAndBindOptions options) - where TObject : notnull + where TObject : notnull, IComparable where TKey : notnull => source.SortAndBind(targetList, Comparer.Default, options);