views:

1231

answers:

2

I seem to be having a problem with checking for list equality. In my case, I have two role objects and I want to see if they are equal. Each role contains a name and a List of permissions. Each permission contains just a name.

public class Role : BaseDomain
{
        virtual public String Name { get; set; }
        virtual public IList Permissions { get; set; }
}

public class Permission
{
        virtual public String Name { get; set; }
}

I defined an equals method on both the Role and the Permission objects. These objects are loaded from the database using Nhibernate. This means that the Role actually contains all the Permissions in an object of type NHibernate.Collection.PersistentBag that implements the IList interface.

In the equals method of the Role class I have a condition as follows:

if (!IList.Equals(Permissions, otherObj.Permissions)) return false;

This is always returning false. Even when the Permissions in the list contain objects with identical names in identical order. This would make sense if I hadn't implemented an equals method for the Permission object, but I have.

When I execute a statement like this:

role1.equals(role2);

What happens is that it first goes to the Role object's equals method. Good. The equals method checks the name of the role to see if they're equal. They are. Then checks to see if the Permissions are equals using the code given above.

I have a breakpoint in the equals method of the Permission class as well as the GetHashCode method. When that statement is executed, neither the equals method nor the GetHashCode method on the permission class is called but it always returns false. In fact, I can't seen to figure out what happens in order to determine that the two lists are not equal. What gets executed? I can't even step into that line of code.

This seems like it should work but it doesn't. Anyone have any ideas on whats going on?

+1  A: 

When you compare 2 lists with each other, the Equals method will NOT compare the items that are in that list. It will compare the List object with the other List object.

A List is an object, which has its own 'identity'.

This for instance, will never return true:

List<int> firstList = new List<int>();
List<int> secondList = new List<int>();

firstList.Add(1);
firstList.Add(2);

secondList.Add(1);
secondList.Add(2);


Assert.IsTrue (firstList.Equals(secondList));

The Equals method does not compare the contents of the list, but the list itself. If you want this behaviour, I think that you'll have to implement your own type of List.

Frederik Gheysels
But that simply means that there is no use of the IList.Equals(obj1, obj2) method. This method does the same as obj1==obj2! Why even have this method defined on the IList interface if it provides no additional benefits? Is there a difference between the two that I am missing?
Sana Tapal
The IList interface does not define an Equals method.The List class however does have an Equals method, but, this is because every class in .NET inherits from 'Object', and the Equals method is defined in the 'Object' class.See: http://msdn.microsoft.com/en-us/library/system.object.aspx
Frederik Gheysels
+6  A: 

As Fredrik said Equals doesn't compare content of the lists. But Enumerable.SequenceEquals does. Check http://stackoverflow.com/questions/43500/is-there-a-built-in-method-to-compare-collections-in-c for more info.

Piotr Czapla