IComparable - Newbie qn

G

Guest

//////////////////////
// What I want to do

- Binary search a collection (ArrayList) consisting of objects that
implement IComparable.
- I want IComparable to respond differently depending on the class of object
I'm searching for
- eg.

ArrayList ClusterChains = new ArrayList();
ClusterChains.Add(new Cluster(new FileEntry("Test.txt", 1234)));

// etc.
// I want to be able to do all of the following

ClusterChains.BinarySearch(new Cluster(new FileEntry("Test.txt", 1234)));
ClusterChains.BinarySearch("Test.txt");
ClusterChains.BinarySearch(1234);

//////////////////////
// What I have done to achieve above - Is this ok

// bah these message editing boxes are too small

- Implemetn CompareTo et al for IComparable
- CompareTo responds differently depending on the class of object passed in
- Equals has been overrided but only operates on instances of the same class

ie. // looks like Cluster is actually ClusterChain..

public int CompareTo(object ProvidedObject)
{
int iResult = int.MinValue;
if (ProvidedObject is CFATEntryChain)
{
CFATEntryChain AnotherEntryChain = (CFATEntryChain) ProvidedObject;
iResult =
this.mFATEntry.uCluster.CompareTo(AnotherEntryChain.mFATEntry.uCluster);
}
else if (ProvidedObject is uint)
{
uint uAnotherCluster = (uint) ProvidedObject;
iResult = this.mFATEntry.uCluster.CompareTo(uAnotherCluster);
}
else if (ProvidedObject is string)
{
string sAnotherFileName = (string) ProvidedObject;
iResult = this.mFATEntry.sFileName.CompareTo(sAnotherFileName);
}
else
{
throw(new ArgumentException("CFATEntryChain.CompareTo - Exception,
compared parameter is not a CFATEntryChain"));
}
return iResult;
}

AND

public bool Equals(CFATEntryChain rhs)
{
if (rhs != null)
return this.CompareTo(rhs) == 0;
else
return false;
}

public override bool Equals(object obj)
{
if (obj != null)
{
if((obj is CFATEntryChain))
return this.Equals((CFATEntryChain) obj);
else
return false;
}
else
{
return false;
}
}

Cheers

Steve
 
G

Guest

Thanks for that Nicholas.

I think I can hear the sound of a penny dropping. I'll have a look at
IComparer...
Still it's a bit of a pain to have to provide an IComparer to do Binary
searches on lists.
I guess I should probably provide a class that inherits from ArrayList for
containing my homogenous objects. This would include overloads for
BinarySearch and ?? that wrap the base BinarySearch with IComparers to match
search criteria by object..

It's still a whole lot easier just to check the runtime type info inside
CompareTo..


Nicholas Paldino said:
Steve,

IMO, I don't think what you are doing is the right thing. I believe
that IComparable should be used for the natural comparison critera for a
type to another instance of that type. IComparer should be used for
comparisons to other types, and comparisons which are to be made which are
not natural to the type.

That being said, you should use the overload of BinarySearch which takes
an instance of IComparer, and pass your implementation to it (it will check
the types, and perform the appropriate comparisons).

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

steve said:
//////////////////////
// What I want to do

- Binary search a collection (ArrayList) consisting of objects that
implement IComparable.
- I want IComparable to respond differently depending on the class of
object
I'm searching for
- eg.

ArrayList ClusterChains = new ArrayList();
ClusterChains.Add(new Cluster(new FileEntry("Test.txt", 1234)));

// etc.
// I want to be able to do all of the following

ClusterChains.BinarySearch(new Cluster(new FileEntry("Test.txt", 1234)));
ClusterChains.BinarySearch("Test.txt");
ClusterChains.BinarySearch(1234);

//////////////////////
// What I have done to achieve above - Is this ok

// bah these message editing boxes are too small

- Implemetn CompareTo et al for IComparable
- CompareTo responds differently depending on the class of object passed
in
- Equals has been overrided but only operates on instances of the same
class

ie. // looks like Cluster is actually ClusterChain..

public int CompareTo(object ProvidedObject)
{
int iResult = int.MinValue;
if (ProvidedObject is CFATEntryChain)
{
CFATEntryChain AnotherEntryChain = (CFATEntryChain) ProvidedObject;
iResult =
this.mFATEntry.uCluster.CompareTo(AnotherEntryChain.mFATEntry.uCluster);
}
else if (ProvidedObject is uint)
{
uint uAnotherCluster = (uint) ProvidedObject;
iResult = this.mFATEntry.uCluster.CompareTo(uAnotherCluster);
}
else if (ProvidedObject is string)
{
string sAnotherFileName = (string) ProvidedObject;
iResult = this.mFATEntry.sFileName.CompareTo(sAnotherFileName);
}
else
{
throw(new ArgumentException("CFATEntryChain.CompareTo - Exception,
compared parameter is not a CFATEntryChain"));
}
return iResult;
}

AND

public bool Equals(CFATEntryChain rhs)
{
if (rhs != null)
return this.CompareTo(rhs) == 0;
else
return false;
}

public override bool Equals(object obj)
{
if (obj != null)
{
if((obj is CFATEntryChain))
return this.Equals((CFATEntryChain) obj);
else
return false;
}
else
{
return false;
}
}

Cheers

Steve
 

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