Skip to content

Commit 9b0825f

Browse files
committed
Comparers serialization
1 parent e7db223 commit 9b0825f

40 files changed

+768
-685
lines changed
Lines changed: 58 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,35 @@
1-
// Copyright (C) 2003-2010 Xtensive LLC.
2-
// All rights reserved.
3-
// For conditions of distribution and use, see license.
1+
// Copyright (C) 2008-2021 Xtensive LLC.
2+
// This code is distributed under MIT license terms.
3+
// See the License.txt file in the project root for more information.
44
// Created by: Dmitri Maximov
55
// Created: 2008.01.23
66

77
using System;
88
using System.Collections;
99
using System.Diagnostics;
1010
using System.Runtime.Serialization;
11+
using System.Security;
1112
using Xtensive.Arithmetic;
1213
using Xtensive.Collections;
1314
using Xtensive.Core;
1415

1516

16-
1717
namespace Xtensive.Comparison
1818
{
1919
/// <summary>
2020
/// Base class for <see cref="IAdvancedComparer{T}"/> implementations.
2121
/// </summary>
2222
/// <typeparam name="T">The type to compare.</typeparam>
2323
[Serializable]
24-
public abstract class AdvancedComparerBase<T>: IAdvancedComparer<T>,
24+
public abstract class AdvancedComparerBase<T>: IAdvancedComparer<T>,
25+
ISerializable,
2526
IDeserializationCallback
2627
{
2728
private static Arithmetic<T> cachedArithmetic;
2829
[NonSerialized]
2930
private ThreadSafeDictionary<ComparisonRules, AdvancedComparer<T>> cachedComparers =
3031
ThreadSafeDictionary<ComparisonRules, AdvancedComparer<T>>.Create(new object());
32+
3133
private IComparerProvider provider;
3234
private ValueRangeInfo<T> valueRangeInfo;
3335

@@ -43,28 +45,27 @@ public abstract class AdvancedComparerBase<T>: IAdvancedComparer<T>,
4345
protected readonly int DefaultDirectionMultiplier;
4446

4547
/// <inheritdoc/>
46-
public IComparerProvider Provider
48+
public IComparerProvider Provider
4749
{
4850
[DebuggerStepThrough]
49-
get { return provider; }
51+
get => provider;
5052
}
5153

5254
/// <inheritdoc/>
53-
ComparisonRules IAdvancedComparerBase.ComparisonRules
55+
ComparisonRules IAdvancedComparerBase.ComparisonRules
5456
{
5557
[DebuggerStepThrough]
56-
get { return ComparisonRules; }
58+
get => ComparisonRules;
5759
}
5860

5961
/// <inheritdoc/>
6062
public ValueRangeInfo<T> ValueRangeInfo
6163
{
62-
get { return valueRangeInfo; }
64+
get => valueRangeInfo;
6365
protected set {
64-
if (ComparisonRules.Value.Direction!=Direction.Negative)
65-
valueRangeInfo = value;
66-
else
67-
valueRangeInfo = value.Invert();
66+
valueRangeInfo = ComparisonRules.Value.Direction != Direction.Negative
67+
? value
68+
: value.Invert();
6869
}
6970
}
7071

@@ -77,15 +78,9 @@ public AdvancedComparer<T> ApplyRules(ComparisonRules rules)
7778
}
7879

7980
/// <inheritdoc/>
80-
public virtual Func<T, TSecond, int> GetAsymmetric<TSecond>()
81-
{
82-
throw new NotSupportedException();
83-
}
81+
public virtual Func<T, TSecond, int> GetAsymmetric<TSecond>() => throw new NotSupportedException();
8482

85-
int IComparer.Compare(object x, object y)
86-
{
87-
return Compare((T) x, (T) y);
88-
}
83+
int IComparer.Compare(object x, object y) => Compare((T) x, (T) y);
8984

9085
/// <inheritdoc/>
9186
public abstract int Compare(T x, T y);
@@ -99,24 +94,21 @@ int IComparer.Compare(object x, object y)
9994
/// <inheritdoc/>
10095
public virtual T GetNearestValue(T value, Direction direction)
10196
{
102-
if (!valueRangeInfo.HasDeltaValue)
103-
throw new NotSupportedException();
104-
Arithmetic<T> arithmetic = GetArithmetic();
105-
if (arithmetic==null)
97+
if (!valueRangeInfo.HasDeltaValue) {
10698
throw new NotSupportedException();
107-
108-
if (direction==ComparisonRules.Value.Direction) {
109-
if (valueRangeInfo.HasMaxValue && Equals(value, valueRangeInfo.MaxValue))
110-
return value;
111-
else
112-
return arithmetic.Add(value, valueRangeInfo.DeltaValue);
11399
}
114-
else {
115-
if (valueRangeInfo.HasMinValue && Equals(value, valueRangeInfo.MinValue))
116-
return value;
117-
else
118-
return arithmetic.Subtract(value, valueRangeInfo.DeltaValue);
100+
var arithmetic = GetArithmetic();
101+
if (arithmetic == null) {
102+
throw new NotSupportedException();
119103
}
104+
105+
return direction == ComparisonRules.Value.Direction
106+
? valueRangeInfo.HasMaxValue && Equals(value, valueRangeInfo.MaxValue)
107+
? value
108+
: arithmetic.Add(value, valueRangeInfo.DeltaValue)
109+
: valueRangeInfo.HasMinValue && Equals(value, valueRangeInfo.MinValue)
110+
? value
111+
: arithmetic.Subtract(value, valueRangeInfo.DeltaValue);
120112
}
121113

122114
/// <summary>
@@ -125,8 +117,9 @@ public virtual T GetNearestValue(T value, Direction direction)
125117
/// <returns>Default arithmetic.</returns>
126118
protected static Arithmetic<T> GetArithmetic()
127119
{
128-
if (cachedArithmetic==null)
120+
if (cachedArithmetic == null) {
129121
cachedArithmetic = Arithmetic<T>.Default;
122+
}
130123
return cachedArithmetic;
131124
}
132125

@@ -136,10 +129,9 @@ protected static Arithmetic<T> GetArithmetic()
136129
/// <typeparam name="TTarget">The type to provide the comparer for (by wrapping this comparer).</typeparam>
137130
public AdvancedComparer<TTarget> Cast<TTarget>()
138131
{
139-
if (typeof(TTarget)==typeof(T))
140-
return new AdvancedComparer<TTarget>(this as IAdvancedComparer<TTarget>);
141-
else
142-
return new AdvancedComparer<TTarget>(new CastingComparer<T, TTarget>(new AdvancedComparer<T>(this)));
132+
return typeof(TTarget) == typeof(T)
133+
? new AdvancedComparer<TTarget>(this as IAdvancedComparer<TTarget>)
134+
: new AdvancedComparer<TTarget>(new CastingComparer<T, TTarget>(new AdvancedComparer<T>(this)));
143135
}
144136

145137
/// <summary>
@@ -166,7 +158,15 @@ public AdvancedComparerBase(IComparerProvider provider, ComparisonRules comparis
166158
false, default(T));
167159
this.provider = provider;
168160
ComparisonRules = comparisonRules;
169-
DefaultDirectionMultiplier = comparisonRules.Value.Direction==Direction.Negative ? -1 : 1;
161+
DefaultDirectionMultiplier = comparisonRules.Value.Direction == Direction.Negative ? -1 : 1;
162+
}
163+
164+
public AdvancedComparerBase(SerializationInfo info, StreamingContext context)
165+
{
166+
provider = (IComparerProvider) info.GetValue(nameof(provider), typeof(IComparerProvider));
167+
valueRangeInfo = (ValueRangeInfo<T>) info.GetValue(nameof(valueRangeInfo), typeof(ValueRangeInfo<T>));
168+
ComparisonRules = (ComparisonRules) info.GetValue(nameof(ComparisonRules), typeof(ComparisonRules));
169+
DefaultDirectionMultiplier = info.GetInt32(nameof(DefaultDirectionMultiplier));
170170
}
171171

172172
/// <summary>
@@ -175,13 +175,25 @@ public AdvancedComparerBase(IComparerProvider provider, ComparisonRules comparis
175175
/// <param name="sender"></param>
176176
public virtual void OnDeserialization(object sender)
177177
{
178-
if (provider==null)
178+
if (provider == null) {
179179
provider = ComparerProvider.Default;
180-
else if (provider.GetType()==typeof(ComparerProvider))
180+
}
181+
else if (provider.GetType() == typeof(ComparerProvider)) {
181182
provider = ComparerProvider.Default;
182-
else if (provider is SystemComparerProvider)
183+
}
184+
else if (provider is SystemComparerProvider) {
183185
provider = ComparerProvider.System;
186+
}
184187
cachedComparers = ThreadSafeDictionary<ComparisonRules, AdvancedComparer<T>>.Create(new object());
185188
}
189+
190+
[SecurityCritical]
191+
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
192+
{
193+
info.AddValue(nameof(provider), provider, provider.GetType());
194+
info.AddValue(nameof(valueRangeInfo), valueRangeInfo, valueRangeInfo.GetType());
195+
info.AddValue(nameof(ComparisonRules), ComparisonRules, ComparisonRules.GetType());
196+
info.AddValue(nameof(DefaultDirectionMultiplier), DefaultDirectionMultiplier);
197+
}
186198
}
187199
}
Lines changed: 31 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
// Copyright (C) 2003-2010 Xtensive LLC.
2-
// All rights reserved.
3-
// For conditions of distribution and use, see license.
1+
// Copyright (C) 2008-2021 Xtensive LLC.
2+
// This code is distributed under MIT license terms.
3+
// See the License.txt file in the project root for more information.
44
// Created by:
55
// Created: 2008.03.06
66

77
using System;
8+
using System.Runtime.Serialization;
89
using Xtensive.Conversion;
910
using Xtensive.Core;
1011
using Xtensive.Reflection;
@@ -20,64 +21,51 @@ namespace Xtensive.Comparison
2021
[Serializable]
2122
public sealed class CastingComparer<TSource, TTarget>: AdvancedComparerBase<TTarget>
2223
{
23-
private static readonly Converter<TTarget, TSource> toSource = AdvancedConverterStruct<TTarget, TSource>.Default.Convert;
24-
private static readonly Converter<TSource, TTarget> toTarget = AdvancedConverterStruct<TSource, TTarget>.Default.Convert;
25-
private readonly AdvancedComparer<TSource> sourceComparer;
26-
27-
internal class AsymmetricCompareHandler<TSecond>:
24+
private class AsymmetricCompareHandler<TSecond> :
2825
IComparer<TTarget, TSecond>
2926
{
3027
private readonly Func<TSource, TSecond, int> baseCompare;
3128

32-
public int Compare(TTarget x, TSecond y)
33-
{
34-
return baseCompare(toSource(x), y);
35-
}
29+
public int Compare(TTarget x, TSecond y) => baseCompare(ToSource(x), y);
3630

3731
public AsymmetricCompareHandler(Func<TSource, TSecond, int> baseCompare)
3832
{
3933
this.baseCompare = baseCompare;
4034
}
4135
}
4236

37+
private static readonly Converter<TTarget, TSource> ToSource = AdvancedConverterStruct<TTarget, TSource>.Default.Convert;
38+
private static readonly Converter<TSource, TTarget> ToTarget = AdvancedConverterStruct<TSource, TTarget>.Default.Convert;
39+
40+
private readonly AdvancedComparer<TSource> sourceComparer;
41+
4342
/// <inheritdoc/>
4443
protected override IAdvancedComparer<TTarget> CreateNew(ComparisonRules rules)
45-
{
46-
return new CastingComparer<TSource, TTarget>(sourceComparer.ApplyRules(rules));
47-
}
44+
=> new CastingComparer<TSource, TTarget>(sourceComparer.ApplyRules(rules));
4845

4946
/// <inheritdoc/>
5047
public override int Compare(TTarget x, TTarget y)
51-
{
52-
return sourceComparer.Compare(toSource(x), toSource(y));
53-
}
48+
=> sourceComparer.Compare(ToSource(x), ToSource(y));
5449

5550
/// <inheritdoc/>
56-
public override bool Equals(TTarget x, TTarget y)
57-
{
58-
return sourceComparer.Equals(toSource(x), toSource(y));
59-
}
51+
public override bool Equals(TTarget x, TTarget y) => sourceComparer.Equals(ToSource(x), ToSource(y));
6052

6153
/// <inheritdoc/>
62-
public override int GetHashCode(TTarget obj)
63-
{
64-
return sourceComparer.GetHashCode(toSource(obj));
65-
}
54+
public override int GetHashCode(TTarget obj) => sourceComparer.GetHashCode(ToSource(obj));
6655

6756
/// <inheritdoc/>
68-
public override TTarget GetNearestValue(TTarget value, Direction direction)
69-
{
70-
return toTarget(sourceComparer.GetNearestValue(toSource(value), direction));
71-
}
57+
public override TTarget GetNearestValue(TTarget value, Direction direction) => ToTarget(sourceComparer.GetNearestValue(ToSource(value), direction));
7258

7359
/// <inheritdoc/>
7460
public override Func<TTarget, TSecond, int> GetAsymmetric<TSecond>()
7561
{
76-
Func<TSource, TSecond, int> asymmetricCompare = sourceComparer.GetAsymmetric<TSecond>();
77-
if (asymmetricCompare == null)
62+
var asymmetricCompare = sourceComparer.GetAsymmetric<TSecond>();
63+
if (asymmetricCompare == null) {
7864
throw new NotSupportedException();
79-
AsymmetricCompareHandler<TSecond> h = new AsymmetricCompareHandler<TSecond>(asymmetricCompare);
80-
return h.Compare;
65+
}
66+
67+
var handler = new AsymmetricCompareHandler<TSecond>(asymmetricCompare);
68+
return handler.Compare;
8169
}
8270

8371

@@ -90,15 +78,20 @@ public CastingComparer(AdvancedComparer<TSource> sourceComparer)
9078
: base(sourceComparer.Provider, sourceComparer.ComparisonRules)
9179
{
9280
this.sourceComparer = sourceComparer;
93-
ValueRangeInfo<TSource> vi = sourceComparer.ValueRangeInfo;
81+
var vi = sourceComparer.ValueRangeInfo;
9482
ValueRangeInfo =
9583
new ValueRangeInfo<TTarget>(
9684
vi.HasMinValue,
97-
vi.HasMinValue ? toTarget(vi.MinValue) : default(TTarget),
85+
vi.HasMinValue ? ToTarget(vi.MinValue) : default(TTarget),
9886
vi.HasMaxValue,
99-
vi.HasMaxValue ? toTarget(vi.MaxValue) : default(TTarget),
87+
vi.HasMaxValue ? ToTarget(vi.MaxValue) : default(TTarget),
10088
vi.HasDeltaValue,
101-
vi.HasDeltaValue ? toTarget(vi.DeltaValue) : default(TTarget));
89+
vi.HasDeltaValue ? ToTarget(vi.DeltaValue) : default(TTarget));
90+
}
91+
92+
public CastingComparer(SerializationInfo info, StreamingContext context)
93+
: base(info, context)
94+
{
10295
}
10396
}
10497
}

0 commit comments

Comments
 (0)