where TKey : notnull, IComparable

This commit is contained in:
neuecc 2021-09-10 14:43:42 +09:00
parent 56e780ba35
commit 35c4d2eb4d
10 changed files with 28 additions and 37 deletions

View File

@ -51,19 +51,19 @@ namespace ObservableCollections
public static class ObservableCollectionsExtensions public static class ObservableCollectionsExtensions
{ {
public static ISynchronizedView<T, TView> CreateSortedView<T, TKey, TView>(this IObservableCollection<T> source, Func<T, TKey> identitySelector, Func<T, TView> transform, IComparer<T> comparer) public static ISynchronizedView<T, TView> CreateSortedView<T, TKey, TView>(this IObservableCollection<T> source, Func<T, TKey> identitySelector, Func<T, TView> transform, IComparer<T> comparer)
where TKey : IComparable<TKey>
{ {
return new SortedView<T, TKey, TView>(source, identitySelector, transform, comparer); return new SortedView<T, TKey, TView>(source, identitySelector, transform, comparer);
} }
public static ISynchronizedView<T, TView> CreateSortedView<T, TKey, TView>(this IObservableCollection<T> source, Func<T, TKey> identitySelector, Func<T, TView> transform, IComparer<TView> viewComparer) public static ISynchronizedView<T, TView> CreateSortedView<T, TKey, TView>(this IObservableCollection<T> source, Func<T, TKey> identitySelector, Func<T, TView> transform, IComparer<TView> viewComparer)
where TKey : IComparable<TKey>
{ {
return new SortedViewViewComparer<T, TKey, TView>(source, identitySelector, transform, viewComparer); return new SortedViewViewComparer<T, TKey, TView>(source, identitySelector, transform, viewComparer);
} }
public static ISynchronizedView<T, TView> CreateSortedView<T, TKey, TView, TCompare>(this IObservableCollection<T> source, Func<T, TKey> identitySelector, Func<T, TView> transform, Func<T, TCompare> compareSelector, bool ascending = true) public static ISynchronizedView<T, TView> CreateSortedView<T, TKey, TView, TCompare>(this IObservableCollection<T> source, Func<T, TKey> identitySelector, Func<T, TView> transform, Func<T, TCompare> compareSelector, bool ascending = true)
where TKey : IComparable<TKey>
{ {
return source.CreateSortedView(identitySelector, transform, new AnonymousComparer<T, TCompare>(compareSelector, ascending)); return source.CreateSortedView(identitySelector, transform, new AnonymousComparer<T, TCompare>(compareSelector, ascending));
} }

View File

@ -7,7 +7,7 @@ using System.Linq;
namespace ObservableCollections.Internal namespace ObservableCollections.Internal
{ {
internal class SortedView<T, TKey, TView> : ISynchronizedView<T, TView> internal class SortedView<T, TKey, TView> : ISynchronizedView<T, TView>
where TKey : IComparable<TKey>
{ {
readonly IObservableCollection<T> source; readonly IObservableCollection<T> source;
readonly Func<T, TView> transform; readonly Func<T, TView> transform;

View File

@ -7,7 +7,7 @@ using System.Linq;
namespace ObservableCollections.Internal namespace ObservableCollections.Internal
{ {
internal class SortedViewViewComparer<T, TKey, TView> : ISynchronizedView<T, TView> internal class SortedViewViewComparer<T, TKey, TView> : ISynchronizedView<T, TView>
where TKey : IComparable<TKey>
{ {
readonly IObservableCollection<T> source; readonly IObservableCollection<T> source;
readonly Func<T, TView> transform; readonly Func<T, TView> transform;

View File

@ -15,17 +15,6 @@ namespace ObservableCollections
return new View<TView>(this, transform); return new View<TView>(this, transform);
} }
// using key implicitly
public ISynchronizedView<KeyValuePair<TKey, TValue>, TView> CreateSortedView<TView>(Func<KeyValuePair<TKey, TValue>, TView> transform, IComparer<KeyValuePair<TKey, TValue>> comparer)
{
return this.CreateSortedView(x => x.Key, transform, comparer);
}
public ISynchronizedView<KeyValuePair<TKey, TValue>, TView> CreateSortedView<TView>(Func<KeyValuePair<TKey, TValue>, TView> transform, IComparer<TView> viewComparer)
{
return this.CreateSortedView(x => x.Key, transform, viewComparer);
}
class View<TView> : ISynchronizedView<KeyValuePair<TKey, TValue>, TView> class View<TView> : ISynchronizedView<KeyValuePair<TKey, TValue>, TView>
{ {
readonly ObservableDictionary<TKey, TValue> source; readonly ObservableDictionary<TKey, TValue> source;

View File

@ -51,19 +51,19 @@ namespace ObservableCollections
public static class ObservableCollectionsExtensions public static class ObservableCollectionsExtensions
{ {
public static ISynchronizedView<T, TView> CreateSortedView<T, TKey, TView>(this IObservableCollection<T> source, Func<T, TKey> identitySelector, Func<T, TView> transform, IComparer<T> comparer) public static ISynchronizedView<T, TView> CreateSortedView<T, TKey, TView>(this IObservableCollection<T> source, Func<T, TKey> identitySelector, Func<T, TView> transform, IComparer<T> comparer)
where TKey : notnull where TKey : notnull, IComparable<TKey>
{ {
return new SortedView<T, TKey, TView>(source, identitySelector, transform, comparer); return new SortedView<T, TKey, TView>(source, identitySelector, transform, comparer);
} }
public static ISynchronizedView<T, TView> CreateSortedView<T, TKey, TView>(this IObservableCollection<T> source, Func<T, TKey> identitySelector, Func<T, TView> transform, IComparer<TView> viewComparer) public static ISynchronizedView<T, TView> CreateSortedView<T, TKey, TView>(this IObservableCollection<T> source, Func<T, TKey> identitySelector, Func<T, TView> transform, IComparer<TView> viewComparer)
where TKey : notnull where TKey : notnull, IComparable<TKey>
{ {
return new SortedViewViewComparer<T, TKey, TView>(source, identitySelector, transform, viewComparer); return new SortedViewViewComparer<T, TKey, TView>(source, identitySelector, transform, viewComparer);
} }
public static ISynchronizedView<T, TView> CreateSortedView<T, TKey, TView, TCompare>(this IObservableCollection<T> source, Func<T, TKey> identitySelector, Func<T, TView> transform, Func<T, TCompare> compareSelector, bool ascending = true) public static ISynchronizedView<T, TView> CreateSortedView<T, TKey, TView, TCompare>(this IObservableCollection<T> source, Func<T, TKey> identitySelector, Func<T, TView> transform, Func<T, TCompare> compareSelector, bool ascending = true)
where TKey : notnull where TKey : notnull, IComparable<TKey>
{ {
return source.CreateSortedView(identitySelector, transform, new AnonymousComparer<T, TCompare>(compareSelector, ascending)); return source.CreateSortedView(identitySelector, transform, new AnonymousComparer<T, TCompare>(compareSelector, ascending));
} }

View File

@ -7,7 +7,7 @@ using System.Linq;
namespace ObservableCollections.Internal namespace ObservableCollections.Internal
{ {
internal class SortedView<T, TKey, TView> : ISynchronizedView<T, TView> internal class SortedView<T, TKey, TView> : ISynchronizedView<T, TView>
where TKey : notnull where TKey : notnull, IComparable<TKey>
{ {
readonly IObservableCollection<T> source; readonly IObservableCollection<T> source;
readonly Func<T, TView> transform; readonly Func<T, TView> transform;
@ -212,7 +212,13 @@ namespace ObservableCollections.Internal
public int Compare((T value, TKey id) x, (T value, TKey id) y) public int Compare((T value, TKey id) x, (T value, TKey id) y)
{ {
return comparer.Compare(x.value, y.value); var compare = comparer.Compare(x.value, y.value);
if (compare == 0)
{
compare = Comparer<TKey>.Default.Compare(x.id, y.id);
}
return compare;
} }
} }
} }

View File

@ -7,7 +7,7 @@ using System.Linq;
namespace ObservableCollections.Internal namespace ObservableCollections.Internal
{ {
internal class SortedViewViewComparer<T, TKey, TView> : ISynchronizedView<T, TView> internal class SortedViewViewComparer<T, TKey, TView> : ISynchronizedView<T, TView>
where TKey : notnull where TKey : notnull, IComparable<TKey>
{ {
readonly IObservableCollection<T> source; readonly IObservableCollection<T> source;
readonly Func<T, TView> transform; readonly Func<T, TView> transform;
@ -231,7 +231,13 @@ namespace ObservableCollections.Internal
public int Compare((TView view, TKey id) x, (TView view, TKey id) y) public int Compare((TView view, TKey id) x, (TView view, TKey id) y)
{ {
return comparer.Compare(x.view, y.view); var compare = comparer.Compare(x.view, y.view);
if (compare == 0)
{
compare = Comparer<TKey>.Default.Compare(x.id, y.id);
}
return compare;
} }
} }
} }

View File

@ -15,17 +15,6 @@ namespace ObservableCollections
return new View<TView>(this, transform); return new View<TView>(this, transform);
} }
// using key implicitly
public ISynchronizedView<KeyValuePair<TKey, TValue>, TView> CreateSortedView<TView>(Func<KeyValuePair<TKey, TValue>, TView> transform, IComparer<KeyValuePair<TKey, TValue>> comparer)
{
return this.CreateSortedView(x => x.Key, transform, comparer);
}
public ISynchronizedView<KeyValuePair<TKey, TValue>, TView> CreateSortedView<TView>(Func<KeyValuePair<TKey, TValue>, TView> transform, IComparer<TView> viewComparer)
{
return this.CreateSortedView(x => x.Key, transform, viewComparer);
}
class View<TView> : ISynchronizedView<KeyValuePair<TKey, TValue>, TView> class View<TView> : ISynchronizedView<KeyValuePair<TKey, TValue>, TView>
{ {
readonly ObservableDictionary<TKey, TValue> source; readonly ObservableDictionary<TKey, TValue> source;

View File

@ -106,7 +106,7 @@ namespace ObservableCollections.Tests
var dict = new ObservableDictionary<int, int>(); var dict = new ObservableDictionary<int, int>();
var view1 = dict.CreateView(x => new ViewContainer<int>(x.Value)); var view1 = dict.CreateView(x => new ViewContainer<int>(x.Value));
var view2 = dict.CreateSortedView(x => x.Key, x => new ViewContainer<int>(x.Value), x => x.Value, true); var view2 = dict.CreateSortedView(x => x.Key, x => new ViewContainer<int>(x.Value), x => x.Value, true);
var view3 = dict.CreateSortedView(x => new ViewContainer<int>(x.Value), viewComparer: Comparer<ViewContainer<int>>.Default); var view3 = dict.CreateSortedView(x => new ViewContainer<int>(x.Value), x => x.Value, viewComparer: Comparer<ViewContainer<int>>.Default);
var filter1 = new TestFilter2<int>((x, v) => x.Value % 2 == 0); var filter1 = new TestFilter2<int>((x, v) => x.Value % 2 == 0);
var filter2 = new TestFilter2<int>((x, v) => x.Value % 2 == 0); var filter2 = new TestFilter2<int>((x, v) => x.Value % 2 == 0);
var filter3 = new TestFilter2<int>((x, v) => x.Value % 2 == 0); var filter3 = new TestFilter2<int>((x, v) => x.Value % 2 == 0);

View File

@ -24,6 +24,7 @@ namespace PostBuildUtility
// Remove nullable // Remove nullable
{"#nullable disable", "" }, {"#nullable disable", "" },
{"where T : notnull", "" }, {"where T : notnull", "" },
{"where TKey : notnull, IComparable<TKey>", "where TKey : IComparable<TKey>" }, // override project specified
{"where TKey : notnull", "" }, {"where TKey : notnull", "" },
{">?", ">" }, // generics <T>? {">?", ">" }, // generics <T>?
{"T?", "T" }, {"T?", "T" },