tags:

views:

226

answers:

8

I have been trying to check my arraylist to see if an object already exsists, but it always returns false. Does any one have a sugestion to what I am doing wrong with the arrayList.

ArrayList arr;

void Init()
{
   arr = new ArrayList();  

}

void Fred()
{   
   CauseAssignment ca = new CauseAssignment(Param1.Text, Param2.Text);
   if(!arr.Contains(ca))
       arr.Add(ca);

}



 public class CauseAssignment
{
    private string _Path;
    public string Path
    {
        get { return _Path; }
    }

    private string _DelimRootCause;
    public string DelimRootCause
    {
        get { return _DelimRootCause; }
    }

    public CauseAssignment(string path, string delimRootCause)
    {
        _Path = path;
        _DelimRootCause = delimRootCause;
    }
    public override string ToString()
    {
        return _Path;
    }
}
+1  A: 

ArrayList.Contains uses the Equals method on your object to determine whether object exists. Do you want to check for existence based on reference or the values of 'CauseAssignment'? If the latter, ou need to override the Equals method.

logicnp
I have never overridden the Equals method...could you please point me in the right direction
Brad
A: 

arr.Contains(ca) will check to see if the object ca exists on the list and will always return false as it's always a new object.

You'll have to loop over the contents of arr checking the value of each object against the newly created one, by overriding the Equals method.

ChrisF
+1  A: 

If that's your real code, then when Contains() gets called in the third line, it's always false because the arrayList is always empty, since it just got initialized two lines before.

If that's not the issue, you may need to define equals() for your CauseAssignment class.

JacobM
not real code...just there for clarity
Brad
+1  A: 

You need to override the Equals (and GetHashcode) methods for the Contains method to be able to do comparisons as you expect. The Contains uses the Equals method for comparing elements. If your CauseAssignment doesn't implement Equals it uses Object.Equals as the default comparison and that might not be what you pretend.

bruno conde
+5  A: 

The Contains() methods of ArrayList determine equalitys using the implementation of Equals() available on the objects you store.

If you want two different instances of your class to be considered equivalent, you would need to override the Equals() method to return true when they are. You should also, then, overload GetHashCode() for consistency and usability in dictionaries. Here's an example:

public class CauseAssignment
{
    private string _Path;

    /* the rest of your code */

    public override bool Equals( object o )
    { 
        if( o == null || o.GetType() != typeof(CauseAssignment) )
            return false;
        CauseAssignment ca = (CauseAssignment)o;
        return ca._Path.Equals( this._Path );
    }

    public override int GetHashCode()
    {
        return _Path.GetHashCode();
    }
}
LBushkin
My implementation of GetHashCode() assumes that _Path is never null. You may want to improve the code if that's not always the case.
LBushkin
The bottom line is that only you know what makes one CauseAssigment equal to another. That's what Equals() should check. So, for example, this particular implementation is ignoring DelimRootCause when making that check. Maybe that's what you want, maybe not.
JacobM
@JacobM: Your points are valid and well taken. I omitted DelimRootCause just for brevity in my example.
LBushkin
+1  A: 

.Contains() is comparing the object reference in this case, not the property values of that object. You have a couple of options:

  1. Look for a reference that you know exists:

    Object o = myArrayList[i]; if(myArrayList.Contains(o)) .... // returns true

  2. Override the .Equals() method if your class, which will allow the ArrayList to determine if two objects are equal based on your own criteria.

See http://msdn.microsoft.com/en-us/library/ms173147.aspx for examples and further information.

David Lively
+3  A: 

You need to override Equals() and GetHashCode() for Contains() to do what you expect, otherwise it is using object.Equals(), which is just a reference comparison.

In this case you may find it easy to implement Equals() and GetHashCode() by just passing your implementation onto String's.

public override bool Equals(object other) {
    CauseAssignment otherCA = other as CauseAssignment;

    if(otherCA != null) {
        return _Path.Equals(otherCA._Path) && DelimRootCause.Equals(otherCA._DelimRootCause);
    }
    return false;
}
Matt Greer
A: 

Thank You Matt. Been trying to get contains to work on a C5.Arraylist and this answer is the first that worked.

quimbo