Skip to content

Commit 582cfa5

Browse files
authored
[Types] Enhance equality comparison (#376)
1 parent 2912b39 commit 582cfa5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1412
-341
lines changed

src/redmine-net-api/Internals/HashCodeHelper.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ public static int GetHashCode<T>(IList<T> list, int hash) where T : class
4343
return hashCode;
4444
}
4545

46-
hashCode = (hashCode * 13) + list.Count;
46+
hashCode = (hashCode * 17) + list.Count;
4747

4848
foreach (var t in list)
4949
{
50-
hashCode *= 13;
50+
hashCode *= 17;
5151
if (t != null)
5252
{
5353
hashCode += t.GetHashCode();

src/redmine-net-api/Types/Attachment.cs

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
Copyright 2011 - 2023 Adrian Popescu
33
44
Licensed under the Apache License, Version 2.0 (the "License");
@@ -31,7 +31,8 @@ namespace Redmine.Net.Api.Types
3131
/// </summary>
3232
[DebuggerDisplay("{" + nameof(DebuggerDisplay) + ",nq}")]
3333
[XmlRoot(RedmineKeys.ATTACHMENT)]
34-
public sealed class Attachment : Identifiable<Attachment>
34+
public sealed class Attachment :
35+
Identifiable<Attachment>
3536
{
3637
#region Properties
3738
/// <summary>
@@ -186,15 +187,28 @@ public override void WriteJson(JsonWriter writer)
186187
public override bool Equals(Attachment other)
187188
{
188189
if (other == null) return false;
189-
return Id == other.Id
190-
&& FileName == other.FileName
191-
&& FileSize == other.FileSize
192-
&& ContentType == other.ContentType
193-
&& Author == other.Author
194-
&& ThumbnailUrl == other.ThumbnailUrl
195-
&& CreatedOn == other.CreatedOn
196-
&& Description == other.Description
197-
&& ContentUrl == other.ContentUrl;
190+
return base.Equals(other)
191+
&& string.Equals(FileName, other.FileName, StringComparison.OrdinalIgnoreCase)
192+
&& string.Equals(ContentType, other.ContentType, StringComparison.OrdinalIgnoreCase)
193+
&& string.Equals(Description, other.Description, StringComparison.OrdinalIgnoreCase)
194+
&& string.Equals(ContentUrl, other.ContentUrl, StringComparison.OrdinalIgnoreCase)
195+
&& string.Equals(ThumbnailUrl, other.ThumbnailUrl, StringComparison.OrdinalIgnoreCase)
196+
&& Equals(Author, other.Author)
197+
&& FileSize == other.FileSize
198+
&& CreatedOn == other.CreatedOn;
199+
}
200+
201+
/// <summary>
202+
///
203+
/// </summary>
204+
/// <param name="obj"></param>
205+
/// <returns></returns>
206+
public override bool Equals(object obj)
207+
{
208+
if (ReferenceEquals(null, obj)) return false;
209+
if (ReferenceEquals(this, obj)) return true;
210+
if (obj.GetType() != GetType()) return false;
211+
return Equals(obj as Attachment);
198212
}
199213

200214
/// <summary>
@@ -209,15 +223,36 @@ public override int GetHashCode()
209223
hashCode = HashCodeHelper.GetHashCode(FileName, hashCode);
210224
hashCode = HashCodeHelper.GetHashCode(FileSize, hashCode);
211225
hashCode = HashCodeHelper.GetHashCode(ContentType, hashCode);
212-
hashCode = HashCodeHelper.GetHashCode(Author, hashCode);
213-
hashCode = HashCodeHelper.GetHashCode(CreatedOn, hashCode);
214226
hashCode = HashCodeHelper.GetHashCode(Description, hashCode);
215227
hashCode = HashCodeHelper.GetHashCode(ContentUrl, hashCode);
216228
hashCode = HashCodeHelper.GetHashCode(ThumbnailUrl, hashCode);
217-
229+
hashCode = HashCodeHelper.GetHashCode(Author, hashCode);
230+
hashCode = HashCodeHelper.GetHashCode(CreatedOn, hashCode);
218231
return hashCode;
219232
}
220233
}
234+
235+
/// <summary>
236+
///
237+
/// </summary>
238+
/// <param name="left"></param>
239+
/// <param name="right"></param>
240+
/// <returns></returns>
241+
public static bool operator ==(Attachment left, Attachment right)
242+
{
243+
return Equals(left, right);
244+
}
245+
246+
/// <summary>
247+
///
248+
/// </summary>
249+
/// <param name="left"></param>
250+
/// <param name="right"></param>
251+
/// <returns></returns>
252+
public static bool operator !=(Attachment left, Attachment right)
253+
{
254+
return !Equals(left, right);
255+
}
221256
#endregion
222257

223258
private string DebuggerDisplay =>

src/redmine-net-api/Types/ChangeSet.cs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
Copyright 2011 - 2023 Adrian Popescu
33
44
Licensed under the Apache License, Version 2.0 (the "License");
@@ -178,14 +178,36 @@ public override int GetHashCode()
178178
{
179179
unchecked
180180
{
181-
var hashCode = 13;
181+
var hashCode = 17;
182182
hashCode = HashCodeHelper.GetHashCode(Revision, hashCode);
183183
hashCode = HashCodeHelper.GetHashCode(User, hashCode);
184184
hashCode = HashCodeHelper.GetHashCode(Comments, hashCode);
185185
hashCode = HashCodeHelper.GetHashCode(CommittedOn, hashCode);
186186
return hashCode;
187187
}
188188
}
189+
190+
/// <summary>
191+
///
192+
/// </summary>
193+
/// <param name="left"></param>
194+
/// <param name="right"></param>
195+
/// <returns></returns>
196+
public static bool operator ==(ChangeSet left, ChangeSet right)
197+
{
198+
return Equals(left, right);
199+
}
200+
201+
/// <summary>
202+
///
203+
/// </summary>
204+
/// <param name="left"></param>
205+
/// <param name="right"></param>
206+
/// <returns></returns>
207+
public static bool operator !=(ChangeSet left, ChangeSet right)
208+
{
209+
return !Equals(left, right);
210+
}
189211
#endregion
190212

191213
/// <summary>

src/redmine-net-api/Types/CustomField.cs

Lines changed: 49 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -207,23 +207,22 @@ public bool Equals(CustomField other)
207207
{
208208
if (other == null) return false;
209209

210-
return Id == other.Id
211-
&& IsFilter == other.IsFilter
212-
&& IsRequired == other.IsRequired
213-
&& Multiple == other.Multiple
214-
&& Searchable == other.Searchable
215-
&& Visible == other.Visible
216-
&& string.Equals(CustomizedType,other.CustomizedType, StringComparison.OrdinalIgnoreCase)
217-
&& string.Equals(Description,other.Description, StringComparison.OrdinalIgnoreCase)
218-
&& string.Equals(DefaultValue,other.DefaultValue, StringComparison.OrdinalIgnoreCase)
219-
&& string.Equals(FieldFormat,other.FieldFormat, StringComparison.OrdinalIgnoreCase)
220-
&& MaxLength == other.MaxLength
221-
&& MinLength == other.MinLength
222-
&& string.Equals(Name,other.Name, StringComparison.OrdinalIgnoreCase)
223-
&& string.Equals(Regexp,other.Regexp, StringComparison.OrdinalIgnoreCase)
224-
&& PossibleValues.Equals(other.PossibleValues)
225-
&& Roles.Equals(other.Roles)
226-
&& Trackers.Equals(other.Trackers);
210+
return base.Equals(other)
211+
&& string.Equals(CustomizedType, other.CustomizedType, StringComparison.OrdinalIgnoreCase)
212+
&& string.Equals(Description, other.Description, StringComparison.OrdinalIgnoreCase)
213+
&& string.Equals(FieldFormat, other.FieldFormat, StringComparison.OrdinalIgnoreCase)
214+
&& string.Equals(Regexp, other.Regexp, StringComparison.OrdinalIgnoreCase)
215+
&& string.Equals(DefaultValue, other.DefaultValue, StringComparison.Ordinal)
216+
&& MinLength == other.MinLength
217+
&& MaxLength == other.MaxLength
218+
&& IsRequired == other.IsRequired
219+
&& IsFilter == other.IsFilter
220+
&& Searchable == other.Searchable
221+
&& Multiple == other.Multiple
222+
&& Visible == other.Visible
223+
&& Equals(PossibleValues, other.PossibleValues)
224+
&& Equals(Trackers, other.Trackers)
225+
&& Equals(Roles, other.Roles);
227226
}
228227

229228
/// <summary>
@@ -247,27 +246,47 @@ public override int GetHashCode()
247246
{
248247
unchecked
249248
{
250-
var hashCode = 13;
251-
hashCode = HashCodeHelper.GetHashCode(Id, hashCode);
252-
hashCode = HashCodeHelper.GetHashCode(IsFilter, hashCode);
253-
hashCode = HashCodeHelper.GetHashCode(IsRequired, hashCode);
254-
hashCode = HashCodeHelper.GetHashCode(Description, hashCode);
255-
hashCode = HashCodeHelper.GetHashCode(Multiple, hashCode);
256-
hashCode = HashCodeHelper.GetHashCode(Searchable, hashCode);
257-
hashCode = HashCodeHelper.GetHashCode(Visible, hashCode);
249+
var hashCode = base.GetHashCode();
258250
hashCode = HashCodeHelper.GetHashCode(CustomizedType, hashCode);
259-
hashCode = HashCodeHelper.GetHashCode(DefaultValue, hashCode);
251+
hashCode = HashCodeHelper.GetHashCode(Description, hashCode);
260252
hashCode = HashCodeHelper.GetHashCode(FieldFormat, hashCode);
261-
hashCode = HashCodeHelper.GetHashCode(MaxLength, hashCode);
262-
hashCode = HashCodeHelper.GetHashCode(MinLength, hashCode);
263-
hashCode = HashCodeHelper.GetHashCode(Name, hashCode);
264253
hashCode = HashCodeHelper.GetHashCode(Regexp, hashCode);
254+
hashCode = HashCodeHelper.GetHashCode(MinLength, hashCode);
255+
hashCode = HashCodeHelper.GetHashCode(MaxLength, hashCode);
256+
hashCode = HashCodeHelper.GetHashCode(IsRequired, hashCode);
257+
hashCode = HashCodeHelper.GetHashCode(IsFilter, hashCode);
258+
hashCode = HashCodeHelper.GetHashCode(Searchable, hashCode);
259+
hashCode = HashCodeHelper.GetHashCode(Multiple, hashCode);
260+
hashCode = HashCodeHelper.GetHashCode(DefaultValue, hashCode);
261+
hashCode = HashCodeHelper.GetHashCode(Visible, hashCode);
265262
hashCode = HashCodeHelper.GetHashCode(PossibleValues, hashCode);
266-
hashCode = HashCodeHelper.GetHashCode(Roles, hashCode);
267263
hashCode = HashCodeHelper.GetHashCode(Trackers, hashCode);
264+
hashCode = HashCodeHelper.GetHashCode(Roles, hashCode);
268265
return hashCode;
269266
}
270267
}
268+
269+
/// <summary>
270+
///
271+
/// </summary>
272+
/// <param name="left"></param>
273+
/// <param name="right"></param>
274+
/// <returns></returns>
275+
public static bool operator ==(CustomField left, CustomField right)
276+
{
277+
return Equals(left, right);
278+
}
279+
280+
/// <summary>
281+
///
282+
/// </summary>
283+
/// <param name="left"></param>
284+
/// <param name="right"></param>
285+
/// <returns></returns>
286+
public static bool operator !=(CustomField left, CustomField right)
287+
{
288+
return !Equals(left, right);
289+
}
271290
#endregion
272291

273292
private string DebuggerDisplay =>

src/redmine-net-api/Types/CustomFieldPossibleValue.cs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@ public void WriteJson(JsonWriter writer) { }
139139
public bool Equals(CustomFieldPossibleValue other)
140140
{
141141
if (other == null) return false;
142-
return Value == other.Value;
142+
return string.Equals(Value, other.Value, StringComparison.Ordinal)
143+
&& string.Equals(Label, other.Label, StringComparison.Ordinal);
143144
}
144145

145146
/// <summary>
@@ -163,11 +164,34 @@ public override int GetHashCode()
163164
{
164165
unchecked
165166
{
166-
var hashCode = 13;
167+
var hashCode = 17;
167168
hashCode = HashCodeHelper.GetHashCode(Value, hashCode);
169+
hashCode = HashCodeHelper.GetHashCode(Label, hashCode);
168170
return hashCode;
169171
}
170172
}
173+
174+
/// <summary>
175+
///
176+
/// </summary>
177+
/// <param name="left"></param>
178+
/// <param name="right"></param>
179+
/// <returns></returns>
180+
public static bool operator ==(CustomFieldPossibleValue left, CustomFieldPossibleValue right)
181+
{
182+
return Equals(left, right);
183+
}
184+
185+
/// <summary>
186+
///
187+
/// </summary>
188+
/// <param name="left"></param>
189+
/// <param name="right"></param>
190+
/// <returns></returns>
191+
public static bool operator !=(CustomFieldPossibleValue left, CustomFieldPossibleValue right)
192+
{
193+
return !Equals(left, right);
194+
}
171195
#endregion
172196

173197
/// <summary>

src/redmine-net-api/Types/CustomFieldValue.cs

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
Copyright 2011 - 2023 Adrian Popescu
33
44
Licensed under the Apache License, Version 2.0 (the "License");
@@ -30,7 +30,10 @@ namespace Redmine.Net.Api.Types
3030
/// </summary>
3131
[DebuggerDisplay("{" + nameof(DebuggerDisplay) + ",nq}")]
3232
[XmlRoot(RedmineKeys.VALUE)]
33-
public class CustomFieldValue : IXmlSerializable, IJsonSerializable, IEquatable<CustomFieldValue>, ICloneable
33+
public class CustomFieldValue :
34+
IXmlSerializable
35+
,IJsonSerializable
36+
,IEquatable<CustomFieldValue>
3437
{
3538
/// <summary>
3639
///
@@ -166,12 +169,34 @@ public override int GetHashCode()
166169
{
167170
unchecked
168171
{
169-
var hashCode = 13;
172+
var hashCode = 17;
170173
hashCode = HashCodeHelper.GetHashCode(Info, hashCode);
171174
return hashCode;
172175
}
173176
}
174177

178+
/// <summary>
179+
///
180+
/// </summary>
181+
/// <param name="left"></param>
182+
/// <param name="right"></param>
183+
/// <returns></returns>
184+
public static bool operator ==(CustomFieldValue left, CustomFieldValue right)
185+
{
186+
return Equals(left, right);
187+
}
188+
189+
/// <summary>
190+
///
191+
/// </summary>
192+
/// <param name="left"></param>
193+
/// <param name="right"></param>
194+
/// <returns></returns>
195+
public static bool operator !=(CustomFieldValue left, CustomFieldValue right)
196+
{
197+
return !Equals(left, right);
198+
}
199+
175200
#endregion
176201

177202
#region Implementation of IClonable

0 commit comments

Comments
 (0)