← Back to team overview

nunit-core team mailing list archive

[Bug 1157828] Re: EqualityComparer does not respect value-equality for null

 

>From what I recall, the logic for the null checks at the beginning of
the method is something like:

if (a == null && b == null)
  return true;

if (a == null || b == null)
  return false;


Could that be safely replaced with:

if (a == null && b == null)  // or ReferenceEquals if you switch for clarity
  return true;

if (a == null)
  return b.Equals(null);
else if (b == null)
  return a.Equals(null);

?

I don't have the code in front of me, but off the top of my head, I
can't think of any cases where you would still need to do any of the
type-specific comparisons that come before the call to a.Equals(b).  It
seems like a relatively safe way to fix the issue without affecting any
existing calls.

-- 
You received this bug notification because you are a member of NUnit
Developers, which is subscribed to NUnit V2.
https://bugs.launchpad.net/bugs/1157828

Title:
  EqualityComparer does not respect value-equality for null

Status in NUnit V2 Test Framework:
  New

Bug description:
  I am using a third-party library that includes Null Objects with value
  comparisons that return true for null.  However, the NUnit equality
  comparer uses reference equality (via the == operator with
  System.Object references) to check for null and returns false if only
  one input is the null pointer.  This means that the value-equality
  comparison for the custom type is never reached.

  The following is a quick & dirty implementation of a Null Object with
  a few tests that demonstrate the problem:

  public class MyObject
  {
      public static MyObject NullObject = new MyObject(-1);

      public int Value { get; set; }

      public MyObject(int value)
      {
          this.Value = value;
      }

      public static bool operator ==(MyObject left, MyObject right)
      {
          if (ReferenceEquals(left, NullObject) || ReferenceEquals(left, null))
              return (ReferenceEquals(right, NullObject) || ReferenceEquals(right, null));

          else if (ReferenceEquals(right, NullObject) || ReferenceEquals(right, null))
              return false;

          return Equals(left, right);
      }

      public static bool operator !=(MyObject left, MyObject right)
      {
          return !(left == right);
      }
      public override bool Equals(object obj)
      {
          if (ReferenceEquals(obj, NullObject) || ReferenceEquals(obj, null))
              return (ReferenceEquals(this, NullObject));

          else if (ReferenceEquals(this, NullObject))
              return false;

          MyObject myobj = obj as MyObject;
          if (myobj == null)
              return false;

          return this.Value == myobj.Value;
      }

      public override int GetHashCode()
      {
          return base.GetHashCode();
      }

  }

  [TestFixture]
  public class TestNullObject
  {
      // TEST PASSES
      [Test]
      public void TestIsTrue()
      {
          Assert.IsTrue(MyObject.NullObject == null);
          Assert.IsTrue(null == MyObject.NullObject);
      }

      // TESTS FAIL
      [Test]
      public void TestIsNull()
      {
          Assert.IsNull(MyObject.NullObject);
      }

      [Test]
      public void TestAreEqual1()
      {
          Assert.AreEqual(MyObject.NullObject, null);
      }

      [Test]
      public void TestAreEqual2()
      {
          Assert.AreEqual(null, MyObject.NullObject);
      }
  }

To manage notifications about this bug go to:
https://bugs.launchpad.net/nunitv2/+bug/1157828/+subscriptions


Follow ups

References