I'm writing some unit tests and the following assertion fails:
Assert.AreEqual(expected.Episode, actual.Episode);
If I call this instead, it succeeds:
Assert.IsTrue(expected.Episode.Equals(actual.Episode));
I had assumed that Assert.AreEqual()
ultimately calls the Equals()
method for the type it is given, in this case Episode.Equals()
.
However, under the covers in Microsoft.VisualStudio.TestTools.UnitTesting.Assert I found the following code (decompiled by ReSharper):
public static void AreEqual<T>(T expected, T actual, string message, params object[] parameters)
{
if (object.Equals((object)expected, (object)actual))
return;
Assert.HandleFail...
}
This implies to me that the AreEqual()
method is casting both expected
and actual
to object
to force the use of the base Equals()
method rather than the overload I have written in the Episode
class. The base method will simply check to see if the references are the same, which they are not.
I have two questions:
If it's relevant, here is my method:
public bool Equals(Episode other)
{
return Number == other.Number &&
CaseNote.Equals(other.CaseNote) &&
Patient.Equals(other.Patient);
}
It is using object.Equals(object,object)
, which deals with things like:
null
reference? and then goes on to use x.Equals(y)
after it has handled those things. It has to cast them to object
because that is what object.Equals(object,object)
takes . Casting to object
also avoids some complications with Nullable<T>
(because a T?
boxes either to null
or to a regular boxed T
).
However, it could also have been implemented as:
if (EqualityComparer<T>.Default.Equals(expected,actual))
return;
which handles Nullable<T>
, IEquatable<T>
, struct
vs class
, and a few other scenarios without any boxing.
But: the current implementation does the job, and the occasional box isn't the end of the world (and: boxing isn't even an issue if your type is a class
).
In your code you need to override Equals(object other)
as well (and need to override GetHashCode too).
Just add this to your code
public bool Equals(Episode other)
{
return Number == other.Number &&
CaseNote.Equals(other.CaseNote) &&
Patient.Equals(other.Patient);
}
public override bool Equals(object other)
{
Episode castOther = other as Episode;
if(castOther == null)
return false;
return this.Equals(castOther);
}
public override int GetHashCode()
{
//TODO: Implement using the members you used in "Equals(Episode other)"
throw new NotImplmentedExecption();
}
Remember for GetHashCode if two objects are equal they must also return equal hash codes. Here is a quick diagram to help visualize.
You may want to check CaseNote
and Patient
for similar issues.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.