From 3d489a6d9a86c58ca7940d489bfe75f00962f42f Mon Sep 17 00:00:00 2001 From: Paul Irwin Date: Sun, 15 Dec 2024 08:57:17 -0700 Subject: [PATCH] Add operator overrides for public IComparable types, #683 (#1056) * Add operator overrides for IComparable types, #683 --- Lucene.Net.sln.DotSettings | 1 + .../Quality/QualityQuery.cs | 71 ++++++++++++++----- .../VectorHighlight/FieldPhraseList.cs | 55 +++++++++++++- .../VectorHighlight/FieldTermStack.cs | 27 ++++++- .../Surround/Query/SimpleTerm.cs | 34 ++++++++- src/Lucene.Net.Spatial/Prefix/Tree/Cell.cs | 36 ++++++++-- .../Suggest/Fst/FSTCompletion.cs | 38 +++++++++- src/Lucene.Net.Suggest/Suggest/Lookup.cs | 50 ++++++++++--- src/Lucene.Net/Index/IndexCommit.cs | 31 +++++++- src/Lucene.Net/Index/Term.cs | 27 ++++++- src/Lucene.Net/Util/Automaton/State.cs | 30 +++++++- src/Lucene.Net/Util/BytesRef.cs | 25 +++++++ src/Lucene.Net/Util/CharsRef.cs | 25 +++++++ src/Lucene.Net/Util/IntsRef.cs | 25 +++++++ src/Lucene.Net/Util/LongsRef.cs | 25 +++++++ src/Lucene.Net/Util/Mutable/MutableValue.cs | 33 +++++++-- 16 files changed, 483 insertions(+), 50 deletions(-) diff --git a/Lucene.Net.sln.DotSettings b/Lucene.Net.sln.DotSettings index 6fd109800d..dae1019ebe 100644 --- a/Lucene.Net.sln.DotSettings +++ b/Lucene.Net.sln.DotSettings @@ -1,4 +1,5 @@  True + True True True \ No newline at end of file diff --git a/src/Lucene.Net.Benchmark/Quality/QualityQuery.cs b/src/Lucene.Net.Benchmark/Quality/QualityQuery.cs index cc45910d14..28caf01ab4 100644 --- a/src/Lucene.Net.Benchmark/Quality/QualityQuery.cs +++ b/src/Lucene.Net.Benchmark/Quality/QualityQuery.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Globalization; +#nullable enable namespace Lucene.Net.Benchmarks.Quality { @@ -28,13 +29,13 @@ namespace Lucene.Net.Benchmarks.Quality /// /// The ID allows to map the quality query with its judgements. /// - /// The name-value pairs are used by a + /// The name-value pairs are used by a /// /// to create a Lucene . /// /// It is very likely that name-value-pairs would be mapped into fields in a Lucene query, /// but it is up to the QualityQueryParser how to map - e.g. all values in a single field, - /// or each pair as its own field, etc., - and this of course must match the way the + /// or each pair as its own field, etc., - and this of course must match the way the /// searched index was constructed. /// public class QualityQuery : IComparable @@ -49,8 +50,8 @@ public class QualityQuery : IComparable /// The contents of this quality query. public QualityQuery(string queryID, IDictionary nameValPairs) { - this.queryID = queryID; - this.nameValPairs = nameValPairs; + this.queryID = queryID ?? throw new ArgumentNullException(nameof(queryID)); + this.nameValPairs = nameValPairs ?? throw new ArgumentNullException(nameof(nameValPairs)); } /// @@ -66,10 +67,9 @@ public virtual string[] GetNames() /// /// The name whose value should be returned. /// - public virtual string GetValue(string name) + public virtual string? GetValue(string name) { - nameValPairs.TryGetValue(name, out string result); - return result; + return nameValPairs.TryGetValue(name, out string? result) ? result : null; } /// @@ -82,22 +82,57 @@ public virtual string GetValue(string name) /// For a nicer sort of input queries before running them. /// Try first as ints, fall back to string if not int. /// - /// - /// - public virtual int CompareTo(QualityQuery other) + /// The other to compare to. + /// 0 if equal, a negative value if smaller, a positive value if larger. + public virtual int CompareTo(QualityQuery? other) { - try + if (other is null) { - // compare as ints when ids ints - int n = int.Parse(queryID, CultureInfo.InvariantCulture); - int nOther = int.Parse(other.queryID, CultureInfo.InvariantCulture); - return n - nOther; + return 1; } - catch (Exception e) when (e.IsNumberFormatException()) + + if (int.TryParse(queryID, NumberStyles.Integer, CultureInfo.InvariantCulture, out int n) + && int.TryParse(other.queryID, NumberStyles.Integer, CultureInfo.InvariantCulture, out int nOther)) { - // fall back to string comparison - return queryID.CompareToOrdinal(other.queryID); + return n - nOther; } + + // fall back to string comparison + return queryID.CompareToOrdinal(other.queryID); } + + // LUCENENET specific - provide Equals and GetHashCode due to providing operator overrides + public override bool Equals(object? obj) + { + if (obj is null) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != GetType()) return false; + return queryID == ((QualityQuery)obj).queryID; + } + + public override int GetHashCode() => queryID.GetHashCode(); + + #region Operator overrides + // LUCENENET specific - per csharpsquid:S1210, IComparable should override comparison operators + + public static bool operator <(QualityQuery? left, QualityQuery? right) + => left is null ? right is not null : left.CompareTo(right) < 0; + + public static bool operator <=(QualityQuery? left, QualityQuery? right) + => left is null || left.CompareTo(right) <= 0; + + public static bool operator >(QualityQuery? left, QualityQuery? right) + => left is not null && left.CompareTo(right) > 0; + + public static bool operator >=(QualityQuery? left, QualityQuery? right) + => left is null ? right is null : left.CompareTo(right) >= 0; + + public static bool operator ==(QualityQuery? left, QualityQuery? right) + => left?.Equals(right) ?? right is null; + + public static bool operator !=(QualityQuery? left, QualityQuery? right) + => !(left == right); + + #endregion } } diff --git a/src/Lucene.Net.Highlighter/VectorHighlight/FieldPhraseList.cs b/src/Lucene.Net.Highlighter/VectorHighlight/FieldPhraseList.cs index f2f8996add..7ece6682d8 100644 --- a/src/Lucene.Net.Highlighter/VectorHighlight/FieldPhraseList.cs +++ b/src/Lucene.Net.Highlighter/VectorHighlight/FieldPhraseList.cs @@ -442,7 +442,7 @@ public override int GetHashCode() public override bool Equals(object obj) { - if (this == obj) + if (ReferenceEquals(this, obj)) { return true; } @@ -470,6 +470,31 @@ public override bool Equals(object obj) return true; } + #region Operator overrides +#nullable enable + // LUCENENET specific - per csharpsquid:S1210, IComparable should override comparison operators + + public static bool operator <(WeightedPhraseInfo? left, WeightedPhraseInfo? right) + => left is null ? right is not null : left.CompareTo(right) < 0; + + public static bool operator <=(WeightedPhraseInfo? left, WeightedPhraseInfo? right) + => left is null || left.CompareTo(right) <= 0; + + public static bool operator >(WeightedPhraseInfo? left, WeightedPhraseInfo? right) + => left is not null && left.CompareTo(right) > 0; + + public static bool operator >=(WeightedPhraseInfo? left, WeightedPhraseInfo? right) + => left is null ? right is null : left.CompareTo(right) >= 0; + + public static bool operator ==(WeightedPhraseInfo? left, WeightedPhraseInfo? right) + => left?.Equals(right) ?? right is null; + + public static bool operator !=(WeightedPhraseInfo? left, WeightedPhraseInfo? right) + => !(left == right); + +#nullable restore + #endregion + /// /// Term offsets (start + end) /// @@ -512,7 +537,7 @@ public override int GetHashCode() public override bool Equals(object obj) { - if (this == obj) + if (ReferenceEquals(this, obj)) { return true; } @@ -535,12 +560,38 @@ public override bool Equals(object obj) } return true; } + public override string ToString() { StringBuilder sb = new StringBuilder(); sb.Append('(').Append(startOffset).Append(',').Append(endOffset).Append(')'); return sb.ToString(); } + + #region Operator overrides +#nullable enable + // LUCENENET specific - per csharpsquid:S1210, IComparable should override comparison operators + + public static bool operator <(Toffs? left, Toffs? right) + => left is null ? right is not null : left.CompareTo(right) < 0; + + public static bool operator <=(Toffs? left, Toffs? right) + => left is null || left.CompareTo(right) <= 0; + + public static bool operator >(Toffs? left, Toffs? right) + => left is not null && left.CompareTo(right) > 0; + + public static bool operator >=(Toffs? left, Toffs? right) + => left is null ? right is null : left.CompareTo(right) >= 0; + + public static bool operator ==(Toffs? left, Toffs? right) + => left?.Equals(right) ?? right is null; + + public static bool operator !=(Toffs? left, Toffs? right) + => !(left == right); + +#nullable restore + #endregion } } } diff --git a/src/Lucene.Net.Highlighter/VectorHighlight/FieldTermStack.cs b/src/Lucene.Net.Highlighter/VectorHighlight/FieldTermStack.cs index 5c909b1094..b8230ba33c 100644 --- a/src/Lucene.Net.Highlighter/VectorHighlight/FieldTermStack.cs +++ b/src/Lucene.Net.Highlighter/VectorHighlight/FieldTermStack.cs @@ -265,7 +265,7 @@ public override int GetHashCode() public override bool Equals(object obj) { - if (this == obj) + if (ReferenceEquals(this, obj)) { return true; } @@ -284,6 +284,31 @@ public override bool Equals(object obj) } return true; } + + #region Operator overrides +#nullable enable + // LUCENENET specific - per csharpsquid:S1210, IComparable should override comparison operators + + public static bool operator <(TermInfo? left, TermInfo? right) + => left is null ? right is not null : left.CompareTo(right) < 0; + + public static bool operator <=(TermInfo? left, TermInfo? right) + => left is null || left.CompareTo(right) <= 0; + + public static bool operator >(TermInfo? left, TermInfo? right) + => left is not null && left.CompareTo(right) > 0; + + public static bool operator >=(TermInfo? left, TermInfo? right) + => left is null ? right is null : left.CompareTo(right) >= 0; + + public static bool operator ==(TermInfo? left, TermInfo? right) + => left?.Equals(right) ?? right is null; + + public static bool operator !=(TermInfo? left, TermInfo? right) + => !(left == right); + +#nullable restore + #endregion } } } diff --git a/src/Lucene.Net.QueryParser/Surround/Query/SimpleTerm.cs b/src/Lucene.Net.QueryParser/Surround/Query/SimpleTerm.cs index ad9c6dcadd..cf9b006d95 100644 --- a/src/Lucene.Net.QueryParser/Surround/Query/SimpleTerm.cs +++ b/src/Lucene.Net.QueryParser/Surround/Query/SimpleTerm.cs @@ -2,6 +2,7 @@ using Lucene.Net.Index; using System; using System.Text; +#pragma warning disable CS0660, CS0661 // CompareTo is deprecated, so skipping implementing equality members (lucenenet#683) namespace Lucene.Net.QueryParsers.Surround.Query { @@ -28,8 +29,8 @@ namespace Lucene.Net.QueryParsers.Surround.Query public abstract class SimpleTerm : SrndQuery, IDistanceSubQuery, IComparable { protected SimpleTerm(bool quoted) // LUCENENET: CA1012: Abstract types should not have constructors (marked protected) - { - this.quoted = quoted; + { + this.quoted = quoted; } private readonly bool quoted; // LUCENENET: marked readonly @@ -115,5 +116,34 @@ public override Search.Query MakeLuceneQueryFieldNoBoost(string fieldName, Basic { return new SimpleTermRewriteQuery(this, fieldName, qf); } + + #region Operator overrides +#nullable enable + // LUCENENET specific - per csharpsquid:S1210, IComparable should override comparison operators + // NOTE: The CompareTo method is marked as obsolete, but we still need to implement the comparison operators + // since this is public in 4.8. Suppressing the obsolete warning here. + +#pragma warning disable CS0618 // Type or member is obsolete + public static bool operator <(SimpleTerm? left, SimpleTerm? right) + => left is null ? right is not null : left.CompareTo(right) < 0; + + public static bool operator <=(SimpleTerm? left, SimpleTerm? right) + => left is null || left.CompareTo(right) <= 0; + + public static bool operator >(SimpleTerm? left, SimpleTerm? right) + => left is not null && left.CompareTo(right) > 0; + + public static bool operator >=(SimpleTerm? left, SimpleTerm? right) + => left is null ? right is null : left.CompareTo(right) >= 0; +#pragma warning restore CS0618 // Type or member is obsolete + + public static bool operator ==(SimpleTerm? left, SimpleTerm? right) + => left?.Equals(right) ?? right is null; + + public static bool operator !=(SimpleTerm? left, SimpleTerm? right) + => !(left == right); + +#nullable restore + #endregion } } diff --git a/src/Lucene.Net.Spatial/Prefix/Tree/Cell.cs b/src/Lucene.Net.Spatial/Prefix/Tree/Cell.cs index d342144387..9d48a8b57c 100644 --- a/src/Lucene.Net.Spatial/Prefix/Tree/Cell.cs +++ b/src/Lucene.Net.Spatial/Prefix/Tree/Cell.cs @@ -28,13 +28,13 @@ namespace Lucene.Net.Spatial.Prefix.Tree /// /// Represents a grid cell. These are not necessarily thread-safe, although new /// Cell("") (world cell) must be. - /// + /// /// @lucene.experimental /// public abstract class Cell : IComparable { /// - /// LUCENENET specific - we need to set the SpatialPrefixTree before calling overridden + /// LUCENENET specific - we need to set the SpatialPrefixTree before calling overridden /// members of this class, just in case those overridden members require it. This is /// not possible from the subclass because the constructor of the base class runs first. /// So we need to move the reference here and also set it before running the normal constructor @@ -90,7 +90,7 @@ protected Cell(SpatialPrefixTree spatialPrefixTree, string token) { this.token = token.Substring(0, (token.Length - 1) - 0); // LUCENENET specific - calling private instead of virtual to avoid initialization issues - SetLeafInternal(); + SetLeafInternal(); } if (Level == 0) { @@ -178,8 +178,8 @@ private void B_fixLeaf() public virtual bool IsLeaf => m_leaf; /// Note: not supported at level 0. - /// - /// NOTE: When overriding this method, be aware that the constructor of this class calls + /// + /// NOTE: When overriding this method, be aware that the constructor of this class calls /// a private method and not this virtual method. So if you need to override /// the behavior during the initialization, call your own private method from the constructor /// with whatever custom behavior you need. @@ -232,7 +232,7 @@ public virtual byte[] GetTokenBytes() //public Cell getParent(); /// /// Like GetSubCells() but with the results filtered by a shape. If - /// that shape is a then it must call + /// that shape is a then it must call /// . The returned cells /// should have ShapeRel set to their relation with /// . In addition, @@ -337,5 +337,27 @@ public override string ToString() #endregion + #region Operator overrides + // LUCENENET specific - per csharpsquid:S1210, IComparable should override comparison operators + + public static bool operator <(Cell? left, Cell? right) + => left is null ? right is not null : left.CompareTo(right) < 0; + + public static bool operator <=(Cell? left, Cell? right) + => left is null || left.CompareTo(right) <= 0; + + public static bool operator >(Cell? left, Cell? right) + => left is not null && left.CompareTo(right) > 0; + + public static bool operator >=(Cell? left, Cell? right) + => left is null ? right is null : left.CompareTo(right) >= 0; + + public static bool operator ==(Cell? left, Cell? right) + => left?.Equals(right) ?? right is null; + + public static bool operator !=(Cell? left, Cell? right) + => !(left == right); + + #endregion } -} \ No newline at end of file +} diff --git a/src/Lucene.Net.Suggest/Suggest/Fst/FSTCompletion.cs b/src/Lucene.Net.Suggest/Suggest/Fst/FSTCompletion.cs index a2a4f90387..06587b33ca 100644 --- a/src/Lucene.Net.Suggest/Suggest/Fst/FSTCompletion.cs +++ b/src/Lucene.Net.Suggest/Suggest/Fst/FSTCompletion.cs @@ -46,10 +46,10 @@ public sealed class Completion : IComparable { /// /// UTF-8 bytes of the suggestion - public BytesRef Utf8 { get; private set; } + public BytesRef Utf8 { get; } /// /// source bucket (weight) of the suggestion - public int Bucket { get; private set; } + public int Bucket { get; } internal Completion(BytesRef key, int bucket) { @@ -67,6 +67,40 @@ public int CompareTo(Completion o) { return this.Utf8.CompareTo(o.Utf8); } + + // LUCENENET specific - per CS0660 and CS0661, we need to override Equals and GetHashCode + // ReSharper disable once BaseObjectEqualsIsObjectEquals + // ReSharper disable once RedundantOverriddenMember + public override bool Equals(object obj) => base.Equals(obj); + + // ReSharper disable once BaseObjectGetHashCodeCallInGetHashCode + // ReSharper disable once RedundantOverriddenMember + public override int GetHashCode() => base.GetHashCode(); + + #region Operator overrides +#nullable enable + // LUCENENET specific - per csharpsquid:S1210, IComparable should override comparison operators + + public static bool operator <(Completion? left, Completion? right) + => left is null ? right is not null : left.CompareTo(right) < 0; + + public static bool operator <=(Completion? left, Completion? right) + => left is null || left.CompareTo(right) <= 0; + + public static bool operator >(Completion? left, Completion? right) + => left is not null && left.CompareTo(right) > 0; + + public static bool operator >=(Completion? left, Completion? right) + => left is null ? right is null : left.CompareTo(right) >= 0; + + public static bool operator ==(Completion? left, Completion? right) + => left?.Equals(right) ?? right is null; + + public static bool operator !=(Completion? left, Completion? right) + => !(left == right); + +#nullable restore + #endregion } /// diff --git a/src/Lucene.Net.Suggest/Suggest/Lookup.cs b/src/Lucene.Net.Suggest/Suggest/Lookup.cs index a04cb73daa..a644eece33 100644 --- a/src/Lucene.Net.Suggest/Suggest/Lookup.cs +++ b/src/Lucene.Net.Suggest/Suggest/Lookup.cs @@ -39,25 +39,25 @@ public sealed class LookupResult : IComparable { /// /// the key's text - public string Key { get; private set; } + public string Key { get; } /// /// Expert: custom Object to hold the result of a - /// highlighted suggestion. + /// highlighted suggestion. /// - public object HighlightKey { get; private set; } + public object HighlightKey { get; } /// /// the key's weight - public long Value { get; private set; } + public long Value { get; } /// /// the key's payload (null if not present) - public BytesRef Payload { get; private set; } + public BytesRef Payload { get; } /// /// the key's contexts (null if not present) - public IEnumerable Contexts { get; private set; } + public IEnumerable Contexts { get; } /// /// Create a new result from a key+weight pair. @@ -122,6 +122,38 @@ public int CompareTo(LookupResult o) { return CHARSEQUENCE_COMPARER.Compare(Key, o.Key); } + + // LUCENENET specific - per CS0660 and CS0661, we need to override Equals and GetHashCode + // ReSharper disable once BaseObjectEqualsIsObjectEquals + // ReSharper disable once RedundantOverriddenMember + public override bool Equals(object obj) => base.Equals(obj); + + // ReSharper disable once BaseObjectGetHashCodeCallInGetHashCode + // ReSharper disable once RedundantOverriddenMember + public override int GetHashCode() => base.GetHashCode(); + + #region Operator overrides + // LUCENENET specific - per csharpsquid:S1210, IComparable should override comparison operators + + public static bool operator <(LookupResult left, LookupResult right) + => left is null ? right is not null : left.CompareTo(right) < 0; + + public static bool operator <=(LookupResult left, LookupResult right) + => left is null || left.CompareTo(right) <= 0; + + public static bool operator >(LookupResult left, LookupResult right) + => left is not null && left.CompareTo(right) > 0; + + public static bool operator >=(LookupResult left, LookupResult right) + => left is null ? right is null : left.CompareTo(right) >= 0; + + public static bool operator ==(LookupResult left, LookupResult right) + => left?.Equals(right) ?? right is null; + + public static bool operator !=(LookupResult left, LookupResult right) + => !(left == right); + + #endregion } /// @@ -129,7 +161,7 @@ public int CompareTo(LookupResult o) /// public static readonly IComparer CHARSEQUENCE_COMPARER = new CharSequenceComparer(); - // LUCENENET: It is no longer good practice to use binary serialization. + // LUCENENET: It is no longer good practice to use binary serialization. // See: https://github.com/dotnet/corefx/issues/23584#issuecomment-325724568 #if FEATURE_SERIALIZABLE [Serializable] @@ -201,7 +233,7 @@ public LookupResult[] GetResults() } /// - /// Sole constructor. (For invocation by subclass + /// Sole constructor. (For invocation by subclass /// constructors, typically implicit.) /// protected Lookup() // LUCENENET: CA1012: Abstract types should not have constructors (marked protected) @@ -306,4 +338,4 @@ public virtual IList DoLookup(string key, bool onlyMorePopular, in /// ram size of the lookup implementation in bytes public abstract long GetSizeInBytes(); } -} \ No newline at end of file +} diff --git a/src/Lucene.Net/Index/IndexCommit.cs b/src/Lucene.Net/Index/IndexCommit.cs index 3caabec528..303aa328ec 100644 --- a/src/Lucene.Net/Index/IndexCommit.cs +++ b/src/Lucene.Net/Index/IndexCommit.cs @@ -117,8 +117,8 @@ public override int GetHashCode() public abstract long Generation { get; } /// - /// Returns userData, previously passed to - /// } for this commit. + /// Returns userData, previously passed to + /// } for this commit. /// The dictionary is -> . /// public abstract IDictionary UserData { get; } @@ -145,5 +145,30 @@ public virtual int CompareTo(IndexCommit commit) return 0; } } + + #region Operator overrides +#nullable enable + // LUCENENET specific - per csharpsquid:S1210, IComparable should override comparison operators + + public static bool operator <(IndexCommit? left, IndexCommit? right) + => left is null ? right is not null : left.CompareTo(right) < 0; + + public static bool operator <=(IndexCommit? left, IndexCommit? right) + => left is null || left.CompareTo(right) <= 0; + + public static bool operator >(IndexCommit? left, IndexCommit? right) + => left is not null && left.CompareTo(right) > 0; + + public static bool operator >=(IndexCommit? left, IndexCommit? right) + => left is null ? right is null : left.CompareTo(right) >= 0; + + public static bool operator ==(IndexCommit? left, IndexCommit? right) + => left?.Equals(right) ?? right is null; + + public static bool operator !=(IndexCommit? left, IndexCommit? right) + => !(left == right); + +#nullable restore + #endregion } -} \ No newline at end of file +} diff --git a/src/Lucene.Net/Index/Term.cs b/src/Lucene.Net/Index/Term.cs index e7841ca78c..6e76a79517 100644 --- a/src/Lucene.Net/Index/Term.cs +++ b/src/Lucene.Net/Index/Term.cs @@ -189,5 +189,30 @@ public override string ToString() { return Field + ":" + Text; } + + #region Operator overrides +#nullable enable + // LUCENENET specific - per csharpsquid:S1210, IComparable should override comparison operators + + public static bool operator <(Term? left, Term? right) + => left is null ? right is not null : left.CompareTo(right) < 0; + + public static bool operator <=(Term? left, Term? right) + => left is null || left.CompareTo(right) <= 0; + + public static bool operator >(Term? left, Term? right) + => left is not null && left.CompareTo(right) > 0; + + public static bool operator >=(Term? left, Term? right) + => left is null ? right is null : left.CompareTo(right) >= 0; + + public static bool operator ==(Term? left, Term? right) + => left?.Equals(right) ?? right is null; + + public static bool operator !=(Term? left, Term? right) + => !(left == right); + +#nullable restore + #endregion } -} \ No newline at end of file +} diff --git a/src/Lucene.Net/Util/Automaton/State.cs b/src/Lucene.Net/Util/Automaton/State.cs index 898bdff630..ccc5ca5aff 100644 --- a/src/Lucene.Net/Util/Automaton/State.cs +++ b/src/Lucene.Net/Util/Automaton/State.cs @@ -360,17 +360,45 @@ public virtual int CompareTo(State s) return s.id - id; } - // LUCENENET NOTE: DO NOT IMPLEMENT Equals()!!! + // LUCENENET NOTE: DO NOT IMPLEMENT Equals() with structural equality!!! // Although it doesn't match GetHashCode(), checking for // reference equality is by design. // Implementing Equals() causes difficult to diagnose // IndexOutOfRangeExceptions when using FuzzyTermsEnum. // See GH-296. + // Overriding here to prevent CS0660 warning due to defining the == operator. + // ReSharper disable once BaseObjectEqualsIsObjectEquals + public override bool Equals(object obj) => base.Equals(obj); [MethodImpl(MethodImplOptions.AggressiveInlining)] public override int GetHashCode() { return id; } + + #region Operator overrides +#nullable enable + // LUCENENET specific - per csharpsquid:S1210, IComparable should override comparison operators + + public static bool operator <(State? left, State? right) + => left is null ? right is not null : left.CompareTo(right) < 0; + + public static bool operator <=(State? left, State? right) + => left is null || left.CompareTo(right) <= 0; + + public static bool operator >(State? left, State? right) + => left is not null && left.CompareTo(right) > 0; + + public static bool operator >=(State? left, State? right) + => left is null ? right is null : left.CompareTo(right) >= 0; + + public static bool operator ==(State? left, State? right) + => left is null ? right is null : ReferenceEquals(left, right); + + public static bool operator !=(State? left, State? right) + => !(left == right); + +#nullable restore + #endregion } } diff --git a/src/Lucene.Net/Util/BytesRef.cs b/src/Lucene.Net/Util/BytesRef.cs index b381f31eb8..8012c77282 100644 --- a/src/Lucene.Net/Util/BytesRef.cs +++ b/src/Lucene.Net/Util/BytesRef.cs @@ -400,6 +400,31 @@ public bool IsValid() } return true; } + + #region Operator overrides +#nullable enable + // LUCENENET specific - per csharpsquid:S1210, IComparable should override comparison operators + + public static bool operator <(BytesRef? left, BytesRef? right) + => left is null ? right is not null : left.CompareTo(right) < 0; + + public static bool operator <=(BytesRef? left, BytesRef? right) + => left is null || left.CompareTo(right) <= 0; + + public static bool operator >(BytesRef? left, BytesRef? right) + => left is not null && left.CompareTo(right) > 0; + + public static bool operator >=(BytesRef? left, BytesRef? right) + => left is null ? right is null : left.CompareTo(right) >= 0; + + public static bool operator ==(BytesRef? left, BytesRef? right) + => left?.Equals(right) ?? right is null; + + public static bool operator !=(BytesRef? left, BytesRef? right) + => !(left == right); + +#nullable restore + #endregion } // LUCENENET: It is no longer good practice to use binary serialization. diff --git a/src/Lucene.Net/Util/CharsRef.cs b/src/Lucene.Net/Util/CharsRef.cs index 14cc2b1de8..48a35debbe 100644 --- a/src/Lucene.Net/Util/CharsRef.cs +++ b/src/Lucene.Net/Util/CharsRef.cs @@ -443,5 +443,30 @@ public bool IsValid() } return true; } + + #region Operator overrides +#nullable enable + // LUCENENET specific - per csharpsquid:S1210, IComparable should override comparison operators + + public static bool operator <(CharsRef? left, CharsRef? right) + => left is null ? right is not null : left.CompareTo(right) < 0; + + public static bool operator <=(CharsRef? left, CharsRef? right) + => left is null || left.CompareTo(right) <= 0; + + public static bool operator >(CharsRef? left, CharsRef? right) + => left is not null && left.CompareTo(right) > 0; + + public static bool operator >=(CharsRef? left, CharsRef? right) + => left is null ? right is null : left.CompareTo(right) >= 0; + + public static bool operator ==(CharsRef? left, CharsRef? right) + => left?.Equals(right) ?? right is null; + + public static bool operator !=(CharsRef? left, CharsRef? right) + => !(left == right); + +#nullable restore + #endregion } } diff --git a/src/Lucene.Net/Util/IntsRef.cs b/src/Lucene.Net/Util/IntsRef.cs index ef90b03e47..901dbcf792 100644 --- a/src/Lucene.Net/Util/IntsRef.cs +++ b/src/Lucene.Net/Util/IntsRef.cs @@ -293,5 +293,30 @@ public bool IsValid() } return true; } + + #region Operator overrides +#nullable enable + // LUCENENET specific - per csharpsquid:S1210, IComparable should override comparison operators + + public static bool operator <(Int32sRef? left, Int32sRef? right) + => left is null ? right is not null : left.CompareTo(right) < 0; + + public static bool operator <=(Int32sRef? left, Int32sRef? right) + => left is null || left.CompareTo(right) <= 0; + + public static bool operator >(Int32sRef? left, Int32sRef? right) + => left is not null && left.CompareTo(right) > 0; + + public static bool operator >=(Int32sRef? left, Int32sRef? right) + => left is null ? right is null : left.CompareTo(right) >= 0; + + public static bool operator ==(Int32sRef? left, Int32sRef? right) + => left?.Equals(right) ?? right is null; + + public static bool operator !=(Int32sRef? left, Int32sRef? right) + => !(left == right); + +#nullable restore + #endregion } } diff --git a/src/Lucene.Net/Util/LongsRef.cs b/src/Lucene.Net/Util/LongsRef.cs index 94cf2f873a..f15578afb4 100644 --- a/src/Lucene.Net/Util/LongsRef.cs +++ b/src/Lucene.Net/Util/LongsRef.cs @@ -292,5 +292,30 @@ public bool IsValid() } return true; } + + #region Operator overrides +#nullable enable + // LUCENENET specific - per csharpsquid:S1210, IComparable should override comparison operators + + public static bool operator <(Int64sRef? left, Int64sRef? right) + => left is null ? right is not null : left.CompareTo(right) < 0; + + public static bool operator <=(Int64sRef? left, Int64sRef? right) + => left is null || left.CompareTo(right) <= 0; + + public static bool operator >(Int64sRef? left, Int64sRef? right) + => left is not null && left.CompareTo(right) > 0; + + public static bool operator >=(Int64sRef? left, Int64sRef? right) + => left is null ? right is null : left.CompareTo(right) >= 0; + + public static bool operator ==(Int64sRef? left, Int64sRef? right) + => left?.Equals(right) ?? right is null; + + public static bool operator !=(Int64sRef? left, Int64sRef? right) + => !(left == right); + +#nullable restore + #endregion } } diff --git a/src/Lucene.Net/Util/Mutable/MutableValue.cs b/src/Lucene.Net/Util/Mutable/MutableValue.cs index 183f30e9e5..62762057c4 100644 --- a/src/Lucene.Net/Util/Mutable/MutableValue.cs +++ b/src/Lucene.Net/Util/Mutable/MutableValue.cs @@ -61,8 +61,8 @@ public virtual int CompareTo(MutableValue other) } - // LUCENENET specific implementation, for use with FunctionFirstPassGroupingCollector - // (note that IComparable does not inherit IComparable, so we need to explicitly + // LUCENENET specific implementation, for use with FunctionFirstPassGroupingCollector + // (note that IComparable does not inherit IComparable, so we need to explicitly // implement here in order to support IComparable) public virtual int CompareTo(object other) { @@ -82,7 +82,7 @@ public virtual int CompareTo(object other) public override bool Equals(object other) { - return (this.GetType() == other.GetType()) && this.EqualsSameType(other); + return this.GetType() == other?.GetType() && this.EqualsSameType(other); } public override abstract int GetHashCode(); @@ -91,5 +91,30 @@ public override string ToString() { return Exists ? ToObject().ToString() : "(null)"; } + + #region Operator overrides +#nullable enable + // LUCENENET specific - per csharpsquid:S1210, IComparable should override comparison operators + + public static bool operator <(MutableValue? left, MutableValue? right) + => left is null ? right is not null : left.CompareTo(right) < 0; + + public static bool operator <=(MutableValue? left, MutableValue? right) + => left is null || left.CompareTo(right) <= 0; + + public static bool operator >(MutableValue? left, MutableValue? right) + => left is not null && left.CompareTo(right) > 0; + + public static bool operator >=(MutableValue? left, MutableValue? right) + => left is null ? right is null : left.CompareTo(right) >= 0; + + public static bool operator ==(MutableValue? left, MutableValue? right) + => left?.Equals(right) ?? right is null; + + public static bool operator !=(MutableValue? left, MutableValue? right) + => !(left == right); + +#nullable restore + #endregion } -} \ No newline at end of file +}