How do I check a list of c++/cli ref items for contains?

A c++/cli ref class DataEntity implements Equals and HashCode. I can check the behavior of the Equals implementation via:

entity1.Equals(entity2);

(C# source) and it works correctly. If I now have a list of such DataEntities and I call Contains(entity) on that list, the Equals method never gets called.

What is the reason for, and how can I use the List.Contains(...) method correcty?

According to the MSDN documentation, the method Contains(...) calls Equals(...)


Example:

C++/CLI source:

public ref class DataEntity : System::Object
{
public:
    DataEntity(System::String^ name, 
        System::String^ val) 
        : m_csName(name),
        m_csValue(val) {}

    System::String^ GetName() { return m_csName; }
    System::String^ GetValue() { return m_csValue; }
    virtual bool Equals(Object^ obj) new {
        if(!obj){
            return false;
        }
        DataEntity^ other = (DataEntity^)obj;
        if(other){
            if(m_csName->Equals(other->m_csName) &&
                m_csValue->Equals(other->m_csValue)){
                    return true;
            }
            return false;
        }
        return false;
    }
    virtual int GetHashCode() new {
        const int iPrime = 17;
        long iResult = 1;
        iResult = iPrime * iResult + m_csName->GetHashCode();
        iResult = iPrime * iResult + m_csValue->GetHashCode();
        return iPrime;
    }

private:
    System::String^ m_csName;       
    System::String^ m_csValue;
};

C# source:

DataEntity entity1 = new DataEntity("Name", "Value");
DataEntity entity2 = new DataEntity("Name", "Value");
Console.WriteLine("Entities 1&2 are Equal: " + entity1.Equals(entity2));

List<DataEntity> entities = new List<DataEntity>();
entities.Add(entity2);
Console.WriteLine("ListContains_Entity2: " + entities.Contains(entity2));

Output:

Entities 1&2 are Equal: True
ListContains_Entity2: False
Jon Skeet
people
quotationmark

My guess is that you've implemented an overload like this:

public bool Equals(DataEntity entity)

That will not be called by Contains. However, if you override the Equals(object) method declared in System.Object, that will be called.

That would explain both symptoms, because

entity1.Equals(entity2)

will use your overload. To check whether it works when using the method declared in Object, just use:

entity1.Equals((object) entity2)

... and I suspect you'll find your method isn't being called.

people

See more on this question at Stackoverflow