Skip to content

Commit 35966ae

Browse files
author
rstam
committed
Implemented IEquatable, !=, ==, Equals and GetHashCode for MongoUser. Tweaked Equals implementation of MongoDBRef.
1 parent dd5fad3 commit 35966ae

File tree

5 files changed

+303
-60
lines changed

5 files changed

+303
-60
lines changed

Driver/Core/MongoDBRef.cs

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,8 @@ private MongoDBRef()
4949
/// <param name="collectionName">The name of the collection that contains the document.</param>
5050
/// <param name="id">The Id of the document.</param>
5151
public MongoDBRef(string collectionName, BsonValue id)
52+
: this(null, collectionName, id)
5253
{
53-
_collectionName = collectionName;
54-
_id = id;
5554
}
5655

5756
/// <summary>
@@ -62,6 +61,14 @@ public MongoDBRef(string collectionName, BsonValue id)
6261
/// <param name="id">The Id of the document.</param>
6362
public MongoDBRef(string databaseName, string collectionName, BsonValue id)
6463
{
64+
if (collectionName == null)
65+
{
66+
throw new ArgumentNullException("collectionName");
67+
}
68+
if (id == null)
69+
{
70+
throw new ArgumentNullException("id");
71+
}
6572
_databaseName = databaseName;
6673
_collectionName = collectionName;
6774
_id = id;
@@ -94,57 +101,68 @@ public BsonValue Id
94101

95102
// public operators
96103
/// <summary>
97-
/// Compares two MongoDBRefs.
104+
/// Determines whether two specified MongoDBRef objects have different values.
98105
/// </summary>
99-
/// <param name="lhs">The first MongoDBRef.</param>
100-
/// <param name="rhs">The other MongoDBRef.</param>
101-
/// <returns>True if the two MongoDBRefs are not equal (or one is null and the other is not).</returns>
106+
/// <param name="lhs">The first value to compare, or null.</param>
107+
/// <param name="rhs">The second value to compare, or null.</param>
108+
/// <returns>True if the value of lhs is different from the value of rhs; otherwise, false.</returns>
102109
public static bool operator !=(MongoDBRef lhs, MongoDBRef rhs)
103110
{
104-
return !(lhs == rhs);
111+
return !MongoDBRef.Equals(lhs, rhs);
105112
}
106113

107114
/// <summary>
108-
/// Compares two MongoDBRefs.
115+
/// Determines whether two specified MongoDBRef objects have the same value.
109116
/// </summary>
110-
/// <param name="lhs">The first MongoDBRef.</param>
111-
/// <param name="rhs">The other MongoDBRef.</param>
112-
/// <returns>True if the two MongoDBRefs are equal (or both null).</returns>
117+
/// <param name="lhs">The first value to compare, or null.</param>
118+
/// <param name="rhs">The second value to compare, or null.</param>
119+
/// <returns>True if the value of lhs is the same as the value of rhs; otherwise, false.</returns>
113120
public static bool operator ==(MongoDBRef lhs, MongoDBRef rhs)
114121
{
115-
return object.Equals(lhs, rhs);
122+
return MongoDBRef.Equals(lhs, rhs);
123+
}
124+
125+
// public static methods
126+
/// <summary>
127+
/// Determines whether two specified MongoDBRef objects have the same value.
128+
/// </summary>
129+
/// <param name="lhs">The first value to compare, or null.</param>
130+
/// <param name="rhs">The second value to compare, or null.</param>
131+
/// <returns>True if the value of lhs is the same as the value of rhs; otherwise, false.</returns>
132+
public static bool Equals(MongoDBRef lhs, MongoDBRef rhs)
133+
{
134+
if ((object)lhs == null) { return (object)rhs == null; }
135+
return lhs.Equals(rhs);
116136
}
117137

118138
// public methods
119139
/// <summary>
120-
/// Compares this MongoDBRef to another one.
140+
/// Determines whether this instance and another specified MongoDBRef object have the same value.
121141
/// </summary>
122-
/// <param name="rhs">The other MongoDBRef.</param>
123-
/// <returns>True if the two MongoDBRefs are equal.</returns>
142+
/// <param name="rhs">The MongoDBRef object to compare to this instance.</param>
143+
/// <returns>True if the value of the rhs parameter is the same as this instance; otherwise, false.</returns>
124144
public bool Equals(MongoDBRef rhs)
125145
{
126-
if (object.ReferenceEquals(rhs, null) || GetType() != rhs.GetType())
127-
{
128-
return false;
129-
}
146+
if ((object)rhs == null || GetType() != rhs.GetType()) { return false; }
147+
if ((object)this == (object)rhs) { return true; }
130148
// note: _databaseName can be null
131-
return object.Equals(_databaseName, rhs._databaseName) && _collectionName.Equals(rhs._collectionName) && _id.Equals(rhs._id);
149+
return string.Equals(_databaseName, rhs._databaseName) && _collectionName.Equals(rhs._collectionName) && _id.Equals(rhs._id);
132150
}
133151

134152
/// <summary>
135-
/// Compares this MongoDBRef to another object.
153+
/// Determines whether this instance and a specified object, which must also be a MongoDBRef object, have the same value.
136154
/// </summary>
137-
/// <param name="obj">The other object.</param>
138-
/// <returns>True if the other objects is a MongoDBRef and is equal to this one.</returns>
155+
/// <param name="obj">The MongoDBRef object to compare to this instance.</param>
156+
/// <returns>True if obj is a MongoDBRef object and its value is the same as this instance; otherwise, false.</returns>
139157
public override bool Equals(object obj)
140158
{
141159
return Equals(obj as MongoDBRef); // works even if obj is null or of a different type
142160
}
143161

144162
/// <summary>
145-
/// Gets the hash code.
163+
/// Returns the hash code for this MongoDBRef object.
146164
/// </summary>
147-
/// <returns>The hash code.</returns>
165+
/// <returns>A 32-bit signed integer hash code.</returns>
148166
public override int GetHashCode()
149167
{
150168
// see Effective Java by Joshua Bloch

Driver/Core/MongoUser.cs

Lines changed: 98 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ namespace MongoDB.Driver
2424
/// Represents a MongoDB user.
2525
/// </summary>
2626
[Serializable]
27-
public class MongoUser
27+
public class MongoUser : IEquatable<MongoUser>
2828
{
2929
// private fields
3030
private string _username;
@@ -39,6 +39,10 @@ public class MongoUser
3939
/// <param name="isReadOnly">Whether the user has read-only access.</param>
4040
public MongoUser(MongoCredentials credentials, bool isReadOnly)
4141
{
42+
if (credentials == null)
43+
{
44+
throw new ArgumentNullException("credentials");
45+
}
4246
_username = credentials.Username;
4347
_passwordHash = HashPassword(credentials.Username, credentials.Password);
4448
_isReadOnly = isReadOnly;
@@ -52,6 +56,14 @@ public MongoUser(MongoCredentials credentials, bool isReadOnly)
5256
/// <param name="isReadOnly">Whether the user has read-only access.</param>
5357
public MongoUser(string username, string passwordHash, bool isReadOnly)
5458
{
59+
if (username == null)
60+
{
61+
throw new ArgumentNullException("username");
62+
}
63+
if (passwordHash == null)
64+
{
65+
throw new ArgumentNullException("passwordHash");
66+
}
5567
_username = username;
5668
_passwordHash = passwordHash;
5769
_isReadOnly = isReadOnly;
@@ -64,7 +76,13 @@ public MongoUser(string username, string passwordHash, bool isReadOnly)
6476
public string Username
6577
{
6678
get { return _username; }
67-
set { _username = value; }
79+
set {
80+
if (value == null)
81+
{
82+
throw new ArgumentNullException("value");
83+
}
84+
_username = value;
85+
}
6886
}
6987

7088
/// <summary>
@@ -73,7 +91,13 @@ public string Username
7391
public string PasswordHash
7492
{
7593
get { return _passwordHash; }
76-
set { _passwordHash = value; }
94+
set {
95+
if (value == null)
96+
{
97+
throw new ArgumentNullException("value");
98+
}
99+
_passwordHash = value;
100+
}
77101
}
78102

79103
/// <summary>
@@ -85,7 +109,42 @@ public bool IsReadOnly
85109
set { _isReadOnly = value; }
86110
}
87111

112+
// public operators
113+
/// <summary>
114+
/// Determines whether two specified MongoUser objects have different values.
115+
/// </summary>
116+
/// <param name="lhs">The first value to compare, or null.</param>
117+
/// <param name="rhs">The second value to compare, or null.</param>
118+
/// <returns>True if the value of lhs is different from the value of rhs; otherwise, false.</returns>
119+
public static bool operator !=(MongoUser lhs, MongoUser rhs)
120+
{
121+
return !MongoUser.Equals(lhs, rhs);
122+
}
123+
124+
/// <summary>
125+
/// Determines whether two specified MongoUser objects have the same value.
126+
/// </summary>
127+
/// <param name="lhs">The first value to compare, or null.</param>
128+
/// <param name="rhs">The second value to compare, or null.</param>
129+
/// <returns>True if the value of lhs is the same as the value of rhs; otherwise, false.</returns>
130+
public static bool operator ==(MongoUser lhs, MongoUser rhs)
131+
{
132+
return MongoUser.Equals(lhs, rhs);
133+
}
134+
88135
// public static methods
136+
/// <summary>
137+
/// Determines whether two specified MongoUser objects have the same value.
138+
/// </summary>
139+
/// <param name="lhs">The first value to compare, or null.</param>
140+
/// <param name="rhs">The second value to compare, or null.</param>
141+
/// <returns>True if the value of lhs is the same as the value of rhs; otherwise, false.</returns>
142+
public static bool Equals(MongoUser lhs, MongoUser rhs)
143+
{
144+
if ((object)lhs == null) { return (object)rhs == null; }
145+
return lhs.Equals(rhs);
146+
}
147+
89148
/// <summary>
90149
/// Calculates the password hash.
91150
/// </summary>
@@ -98,6 +157,42 @@ public static string HashPassword(string username, string password)
98157
}
99158

100159
// public methods
160+
/// <summary>
161+
/// Determines whether this instance and another specified MongoUser object have the same value.
162+
/// </summary>
163+
/// <param name="rhs">The MongoUser object to compare to this instance.</param>
164+
/// <returns>True if the value of the rhs parameter is the same as this instance; otherwise, false.</returns>
165+
public bool Equals(MongoUser rhs)
166+
{
167+
if ((object)rhs == null || GetType() != rhs.GetType()) { return false; }
168+
if ((object)this == (object)rhs) { return true; }
169+
return _username.Equals(rhs._username) && _passwordHash.Equals(rhs._passwordHash) && _isReadOnly.Equals(rhs._isReadOnly);
170+
}
171+
172+
/// <summary>
173+
/// Determines whether this instance and a specified object, which must also be a MongoUser object, have the same value.
174+
/// </summary>
175+
/// <param name="obj">The MongoUser object to compare to this instance.</param>
176+
/// <returns>True if obj is a MongoUser object and its value is the same as this instance; otherwise, false.</returns>
177+
public override bool Equals(object obj)
178+
{
179+
return Equals(obj as MongoUser); // works even if obj is null or of a different type
180+
}
181+
182+
/// <summary>
183+
/// Returns the hash code for this Class1 object.
184+
/// </summary>
185+
/// <returns>A 32-bit signed integer hash code.</returns>
186+
public override int GetHashCode()
187+
{
188+
// see Effective Java by Joshua Bloch
189+
int hash = 17;
190+
hash = 37 * hash + _username.GetHashCode();
191+
hash = 37 * hash + _passwordHash.GetHashCode();
192+
hash = 37 * hash + _isReadOnly.GetHashCode();
193+
return hash;
194+
}
195+
101196
/// <summary>
102197
/// Returns a string representation of the credentials.
103198
/// </summary>

DriverUnitTests/Core/MongoDBRefTests.cs

Lines changed: 65 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -89,43 +89,76 @@ public void TestDocumentRefId()
8989
[Test]
9090
public void TestEqualsWithDatabase()
9191
{
92-
var dbRef1a = new MongoDBRef("database", "collection", 1);
93-
var dbRef1b = new MongoDBRef("database", "collection", 1);
94-
var dbRef2 = new MongoDBRef("database", "collection", 2);
95-
MongoDBRef nullDbRef = null;
96-
97-
Assert.IsFalse(object.ReferenceEquals(dbRef1a, dbRef1b));
98-
Assert.IsTrue(dbRef1a == dbRef1b);
99-
Assert.IsFalse(dbRef1a == dbRef2);
100-
Assert.IsFalse(dbRef1a == null);
101-
Assert.IsFalse(null == dbRef1b);
102-
Assert.IsFalse(dbRef1a == nullDbRef);
103-
Assert.IsFalse(nullDbRef == dbRef1b);
104-
Assert.IsTrue(nullDbRef == null);
105-
Assert.IsTrue(null == nullDbRef);
106-
107-
Assert.AreEqual(dbRef1a.GetHashCode(), dbRef1b.GetHashCode());
92+
var a1 = new MongoDBRef("d", "c", 1);
93+
var a2 = new MongoDBRef("d", "c", 1);
94+
var a3 = a2;
95+
var b = new MongoDBRef("x", "c", 1);
96+
var c = new MongoDBRef("d", "x", 1);
97+
var d = new MongoDBRef("d", "c", 2);
98+
var null1 = (MongoDBRef)null;
99+
var null2 = (MongoDBRef)null;
100+
101+
Assert.AreNotSame(a1, a2);
102+
Assert.AreSame(a2, a3);
103+
Assert.IsTrue(a1.Equals((object)a2));
104+
Assert.IsFalse(a1.Equals((object)null));
105+
Assert.IsFalse(a1.Equals((object)"x"));
106+
107+
Assert.IsTrue(a1 == a2);
108+
Assert.IsTrue(a2 == a3);
109+
Assert.IsFalse(a1 == b);
110+
Assert.IsFalse(a1 == c);
111+
Assert.IsFalse(a1 == d);
112+
Assert.IsFalse(a1 == null1);
113+
Assert.IsFalse(null1 == a1);
114+
Assert.IsTrue(null1 == null2);
115+
116+
Assert.IsFalse(a1 != a2);
117+
Assert.IsFalse(a2 != a3);
118+
Assert.IsTrue(a1 != b);
119+
Assert.IsTrue(a1 != c);
120+
Assert.IsTrue(a1 != d);
121+
Assert.IsTrue(a1 != null1);
122+
Assert.IsTrue(null1 != a1);
123+
Assert.IsFalse(null1 != null2);
124+
125+
Assert.AreEqual(a1.GetHashCode(), a2.GetHashCode());
108126
}
109127

110128
[Test]
111129
public void TestEqualsWithoutDatabase()
112130
{
113-
var dbRef1a = new MongoDBRef("collection", 1);
114-
var dbRef1b = new MongoDBRef("collection", 1);
115-
var dbRef2 = new MongoDBRef("collection", 2);
116-
MongoDBRef nullDbRef = null;
117-
118-
Assert.IsFalse(object.ReferenceEquals(dbRef1a, dbRef1b));
119-
Assert.IsTrue(dbRef1a == dbRef1b);
120-
Assert.IsFalse(dbRef1a == dbRef2);
121-
Assert.IsFalse(dbRef1a == null);
122-
Assert.IsFalse(null == dbRef1b);
123-
Assert.IsFalse(dbRef1a == nullDbRef);
124-
Assert.IsFalse(nullDbRef == dbRef1b);
125-
Assert.IsTrue(nullDbRef == null);
126-
Assert.IsTrue(null == nullDbRef);
127-
128-
Assert.AreEqual(dbRef1a.GetHashCode(), dbRef1b.GetHashCode());
131+
var a1 = new MongoDBRef("c", 1);
132+
var a2 = new MongoDBRef("c", 1);
133+
var a3 = a2;
134+
var b = new MongoDBRef("x", 1);
135+
var c = new MongoDBRef("c", 2);
136+
var null1 = (MongoDBRef)null;
137+
var null2 = (MongoDBRef)null;
138+
139+
Assert.AreNotSame(a1, a2);
140+
Assert.AreSame(a2, a3);
141+
Assert.IsTrue(a1.Equals((object)a2));
142+
Assert.IsFalse(a1.Equals((object)null));
143+
Assert.IsFalse(a1.Equals((object)"x"));
144+
145+
Assert.IsTrue(a1 == a2);
146+
Assert.IsTrue(a2 == a3);
147+
Assert.IsFalse(a1 == b);
148+
Assert.IsFalse(a1 == c);
149+
Assert.IsFalse(a1 == null1);
150+
Assert.IsFalse(null1 == a1);
151+
Assert.IsTrue(null1 == null2);
152+
153+
Assert.IsFalse(a1 != a2);
154+
Assert.IsFalse(a2 != a3);
155+
Assert.IsTrue(a1 != b);
156+
Assert.IsTrue(a1 != c);
157+
Assert.IsTrue(a1 != null1);
158+
Assert.IsTrue(null1 != a1);
159+
Assert.IsFalse(null1 != null2);
160+
161+
Assert.AreEqual(a1.GetHashCode(), a2.GetHashCode());
129162
}
130163

131164
[Test]

0 commit comments

Comments
 (0)