question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Collections.HaveElementAt object is doing reference equals and not checking for IEquatable

See original GitHub issue

Description

(Collections).HaveElementAt is using System.Object.Equals for equality check, and not checking for IEquatable and invoking that if available. Maybe there’s a more appropriate method?

Complete minimal example reproducing the issue

[Test]
public void MyLibrary_Testing()
{
  // Arrange
  var testobj = new TestObject { Index = 0 };
  var testobjCollection = new TestObject[] { testobj };

  // Act
  var result = testobjCollection;

  // Assert
  result.Should().HaveElementAt(0, new TestObj { Index=0 }); //this doesnt work
  result.Should().HaveElementAt(0, testobjCollection[0]); //this works since references are equal
}
public class TestObject : IEquatable<TestObject>
{
  public int Index { get;set; }
  public bool Equals(TestObject other)
  {
    if(other==null) return false;
    if(this.Index != other.Index) return false;
    return true;
  }
}

Expected behavior:

HaveElementAt looks at collection index 0, checks equality by invoking IEquatable since interface was present on TestObject.

Actual behavior:

Output from test:

Message: Expected 

RESTQueryTests.QueryableExtensions_AddPaging_Tests+TestObject
{
   Index = 0
} at index 0, but found 

RESTQueryTests.QueryableExtensions_AddPaging_Tests+TestObject
{
   Index = 0
}.

Clearly basically the same object from IEquatable standpoint, but two different objects from ReferenceEquals standpoint.

Versions

  • Which version of Fluent Assertions are you using? 5.4.1
  • Which .NET runtime and version are you targeting? Net Framework 4.5.2

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
dennisdoomencommented, Jul 12, 2018

From the MSDN docs on IEquatable(T).

If you implement IEquatable<T>, you should also override the base class implementations of Object.Equals(Object) and GetHashCode so that their behavior is consistent with that of the IEquatable<T>.Equals method.

0reactions
ericnewton76commented, Jul 12, 2018

Yes, just figured that out when I added override Equals to TestObj:

https://github.com/ericnewton76/RESTQuery/commit/b562191fe28e0712df3f65d5d9f4d5c0bccdc756

Sorry. Kinda Net 101 mistake right there. Maybe I’ll send a PR for some of the method summaries to remind of that.

Read more comments on GitHub >

github_iconTop Results From Across the Web

c# - If I implement IEquatable<T>, will I lose the option to ...
There are several different things going on here. The first is that IEquatable<T> is not directly related to the == operator.
Read more >
IEquatable<T>.Equals(T) Method (System)
Indicates whether the current object is equal to another object of the same type.
Read more >
The Right Way to do Equality in C# – Aaronontheweb
My personal opinion: in any managed language, checking for referential equality is a pretty bad default - and if you're working with immutable...
Read more >
How to implement IEquatable on ISharedComponentData?
I have a hybrid solution with GameObjectEntity, and I am using SharedComponents to store a reference to certain attributes from the original ...
Read more >
Implementing IEquatable Properly
Explains how to properly implement the IEquatable interface.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found