Skip to content

Commit

Permalink
implement IEquatable, fix Equals, improve GetHashCode (issue #34)
Browse files Browse the repository at this point in the history
  • Loading branch information
WalkerCodeRanger committed Dec 30, 2020
1 parent 61a3b25 commit 4d264be
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 24 deletions.
5 changes: 2 additions & 3 deletions Semver.Test/SemVersionComparisonTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,9 @@ public void EqualsNullTest()
public void EqualsNonSemVersionTest()
{
var v = new SemVersion(1);
// TODO should return false
var ex = Assert.Throws<InvalidCastException>(() => v.Equals(new object()));
var r = v.Equals(new object());

Assert.Equal("Unable to cast object of type 'System.Object' to type 'Semver.SemVersion'.", ex.Message);
Assert.False(r);
}

[Theory]
Expand Down
49 changes: 28 additions & 21 deletions Semver/SemVersion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ namespace Semver
/// Conforms with v2.0.0 of http://semver.org
/// </summary>
#if NETSTANDARD
public sealed class SemVersion : IComparable<SemVersion>, IComparable
public sealed class SemVersion : IComparable<SemVersion>, IComparable, IEquatable<SemVersion>
#else
[Serializable]
public sealed class SemVersion : IComparable<SemVersion>, IComparable, ISerializable
#endif
{
private const string InvalidSemVersionStylesMessage = "An invalid SemVersionStyles value was used.";
private const string InvalidSemVersionStylesMessage = "An invalid SemVersionStyles value was used";

/// <summary>
/// This exception is used with the <see cref="SemVersionParser.Parse"/>
Expand Down Expand Up @@ -626,22 +626,31 @@ private static int CompareComponent(string a, string b, bool nonemptyIsLower = f
/// <returns>
/// <see langword="true"/> if the specified <see cref="object" /> is equal to this instance, otherwise <see langword="false"/>.
/// </returns>
/// <exception cref="InvalidCastException">The <paramref name="obj"/> is not a <see cref="SemVersion"/>.</exception>
public override bool Equals(object obj)
{
if (obj is null)
return Equals(obj as SemVersion);
}

/// <summary>
/// Indicates whether the <see cref="SemVersion"/> is equal to another <see cref="SemVersion"/>.
/// </summary>
/// <param name="other">An object to compare with this object.</param>
/// <returns>
/// <see langword="true"/> if the current object is equal to the <paramref name="other"/> parameter, otherwise <see langword="false"/>.
/// </returns>
public bool Equals(SemVersion other)
{
if (other is null)
return false;

if (ReferenceEquals(this, obj))
if (ReferenceEquals(this, other))
return true;

var other = (SemVersion)obj;

return Major == other.Major
&& Minor == other.Minor
&& Patch == other.Patch
&& string.Equals(Prerelease, other.Prerelease, StringComparison.Ordinal)
&& string.Equals(Metadata, other.Metadata, StringComparison.Ordinal);
&& Minor == other.Minor
&& Patch == other.Patch
&& string.Equals(Prerelease, other.Prerelease, StringComparison.Ordinal)
&& string.Equals(Metadata, other.Metadata, StringComparison.Ordinal);
}

/// <summary>
Expand All @@ -652,16 +661,14 @@ public override bool Equals(object obj)
/// </returns>
public override int GetHashCode()
{
unchecked
{
// TODO verify this. Some versions start result = 17. Some use 37 instead of 31
int result = Major.GetHashCode();
result = result * 31 + Minor.GetHashCode();
result = result * 31 + Patch.GetHashCode();
result = result * 31 + Prerelease.GetHashCode();
result = result * 31 + Metadata.GetHashCode();
return result;
}
// FNV based hash combine generated by VS
var hashCode = 276583904;
hashCode = hashCode * -1521134295 + Major.GetHashCode();
hashCode = hashCode * -1521134295 + Minor.GetHashCode();
hashCode = hashCode * -1521134295 + Patch.GetHashCode();
hashCode = hashCode * -1521134295 + Prerelease.GetHashCode();
hashCode = hashCode * -1521134295 + Metadata.GetHashCode();
return hashCode;
}

#if !NETSTANDARD
Expand Down

0 comments on commit 4d264be

Please sign in to comment.