Contains / Equals

G

Guest

I have a collection class that contains objects of the type of another class
call it Class1, that I have created. The constructor for Class1 takes two integers
These go on to be fields of the class, 'Low' and 'High'

I want the following to happen
MyCollection cn = new MyCollection()
cn.Add(new Class1(1, 2))
cn.Add(new Class1(1, 3))
cn.Add(new Class1(1, 4))
//then I want this to be true
if(cn.Contains(new Class1(1, 3))

//object with Low = 1, High = 3 has been foun


Of course they are reference types, so they are no
the same thing, and it returns false. But in my mind the
are, so I want to be able to program it so that it knows this

I'm pretty sure from the documentation that it is possibl
to determine this using some fancy hash-table based method
and I'd rather do this than a loop
although it is a bit of a minefield and I'm fairly new to this
What do I do - override Class1.Equals()? Overrid
MyCollection.Contains()? Implement IComparable
All of these
I don't need the objects to be ordered, although I do nee
them to behave like value types, but only with regard to th
Contains method
Can anyone give me a starter

Thank
 
D

Dennis Myrén

You would have to override the == operator to implement you own:
public static bool operator == ( Class1 a, Class1 b )
{

return a.Low == b.Low && a.High == b.High;

}

Then in MyCollection, in the Contains method, you step through the items
to check the equality.
 
J

Jon Skeet [C# MVP]

songie D said:
I have a collection class that contains objects of the type of another class,
call it Class1, that I have created. The constructor for Class1 takes two integers.
These go on to be fields of the class, 'Low' and 'High'.

I want the following to happen:
MyCollection cn = new MyCollection();
cn.Add(new Class1(1, 2));
cn.Add(new Class1(1, 3));
cn.Add(new Class1(1, 4));
//then I want this to be true:
if(cn.Contains(new Class1(1, 3)))
{
//object with Low = 1, High = 3 has been found
}

Of course they are reference types, so they are not
the same thing, and it returns false. But in my mind they
are, so I want to be able to program it so that it knows this.

I'm pretty sure from the documentation that it is possible
to determine this using some fancy hash-table based method,
and I'd rather do this than a loop.
although it is a bit of a minefield and I'm fairly new to this.
What do I do - override Class1.Equals()? Override
MyCollection.Contains()? Implement IComparable?
All of these?

All you need to *really* do is override Class1.Equals, but you should
also override Class1.GetHashCode for two reasons:

1) To avoid getting a warning every time you compile :)
2) To allow you use the class as a key in a hashtable

Now how you implement Contains in your collection will depend on how
the collection works in general. An ArrayList would just use a loop, a
hashtable would basically look up the key in the normal way.
 
J

Jon Skeet [C# MVP]

songie D said:
how would I implement GetHashCode to produce a single unique integer out of
two unique integers?

You don't have to - it doesn't need to be unique. It's just preferable
for the same result not to crop up *too* often for different objects.

You could either XOR it (result = a^b) or (as suggested in an excellent
Java book when constructing a hashcode from potentially many others)
use something like result = a*17+b. (The exact details are in the book
- it's the one by Josh Bloch, Elements of Java Style IIRC.)
 
J

Jon Skeet [C# MVP]

songie D said:
OK, thanks Jon.
I've found that if I implement Equals (which means I have to implement GetHashCode)
and operator== (which means I have to implement operator!=) then Contains
works the way I want it to without me overriding it.
I had overridden it, so I didn't need it - so I thought I'd delete the method so it
just used the base class's one instead. But when I had, the base class apparently
didn't have a Contains method. Is this normal? Should it have a Contains method?

What is the base class in this case?
 
J

Jon Skeet [C# MVP]

songie D said:
It's a CollectionBase.

I started a new project, and added a class derived from CollectionBase. But it too didn't
implicitly 'inherit' Contains from CollectionBase, so I presume it's not supposed to.

Or is it?

CollectionBase implements IList.Contains explicitly - so you can't use
it directly in your code without casting to IList, but it *is* there.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top