473,405 Members | 2,282 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

about IComparer and Comparer

Hello!

I'm reading in a book and this can't be correct it says.
"Objects passed to Comparer.Compare() are checked to see if they support
IComparable.
If they do, then that implementation is used"

Assume I have a collection of Item(s) in an ArrayList
This class called Item support the IComparable interface which contains the
CompareTo method
so this method is impemented in class Item.

Now I can sort in the way that this CompareTo is implemented.

Now assume I want to be able to sort the collection of item(s) in another
way then this CompareTo is implementet
so I create an helper class which implement the IComparer interface which
contains method Compare.

So not to my question when object of type Item is passed to the Compare
method that implementation
is used of course not the implementation that exist for the IComparable.

//Tony
Jun 27 '08 #1
10 2512
ArrayList.Sort has several overloads; the parameterless one uses
Comparer.Default, which (as you discussed) will use the objects
IComparable support (if any). If you want a custom sort, there is an
overload (2, actually) that accepts your custom IComparer, in which
case Comparer.Default is *not* used.

Note that in .NET 2.0, it would be better to consider List<T>,
IComparer<T>, IComparable<Tand Comparer<T>.Default.

Marc
Jun 27 '08 #2
On Jun 17, 9:18 am, "Tony" <johansson.anders...@telia.comwrote:
I'm reading in a book and this can't be correct it says.
"Objects passed to Comparer.Compare() are checked to see if they support
IComparable.
If they do, then that implementation is used"
One thing to note is that most of the time you should now be using the
generic Comparer<Tclass and in particular Comparer<T>.Default.
Assume I have a collection of Item(s) in an ArrayList
This class called Item support the IComparable interface which contains the
CompareTo method
so this method is impemented in class Item.

Now I can sort in the way that this CompareTo is implemented.

Now assume I want to be able to sort the collection of item(s) in another
way then this CompareTo is implementet
so I create an helper class which implement the IComparer interface which
contains method Compare.
So far so good - but at that point you don't use the Comparer class,
you just pass an instance of your IComparer implementation into
whatever sorting method you're using.
So not to my question when object of type Item is passed to the Compare
method that implementation
is used of course not the implementation that exist for the IComparable.
The quote you gave specified part of the implementation of
Comparer.Compare. If you're not calling Comparer.Compare, then the
quote is irrelevant. Why would you call Comparer.Compare if you want
to use a custom IComparer implementation?

Perhaps it would help if you'd provide a short but complete example,
and ask what the behaviour is and why for a specific method call.

Jon
Jun 27 '08 #3
Here I have not Complete program enough to be able to answer my question.
Here again I pass an object to this Comparer.Compare() although there is an
Default in between.
>Objects passed to Comparer.Compare() are checked to see if they support
IComparable.
If they do, then that implementation is used"
Below when I pass object to this Comparer.Default.Compare I don't use the
implementation from
IComparable that the text above is claiming I use whatever relevent code I
want.?

So what the text is claiming must be completely nonsens.!

public class Item : IComparable
{
private int steelGrade;
private int heatNumber;
private string mspName;
private string dateTime;
private int optTime;
private ArrayList listOpt;
private ArrayList listDateTime;

public ArrayList ListDateTime
{
set { listDateTime = value; }
get { return listDateTime; }
}

public ArrayList ListOpt
{
set {listOpt = value; }
get { return listOpt; }
}

public int OptTime
{
set { optTime = value; }
get { return optTime; }
}

public string DateTime
{
set { dateTime = value; }
get { return dateTime; }
}

public int Steelgrade
{
set { steelGrade = value; }
get { return steelGrade; }
}

public int HeatNumber
{
set { heatNumber = value; }
get { return heatNumber; }
}

public string MspName
{
set { mspName = value; }
get { return mspName; }
}

public int CompareTo(object right)
{
if (right is Item)
{
Item item = right as Item;
if (this.HeatNumber != item.HeatNumber)
return this.HeatNumber.CompareTo(item.HeatNumber);
else
return this.MspName.CompareTo(item.MspName);
}
else
throw new ArgumentException("Object to compare is not a Item
object");

}
}
public class ItemComparer : IComparer
{
public static IComparer Default = new ItemComparer();

public int Compare(object left, object right)
{
if (left is Item && right is Item)
{
if (((Item)left).Steelgrade != ((Item)right).Steelgrade)
return Comparer.Default.Compare(
((Item)left).Steelgrade, ((Item)right).Steelgrade);
else
return Comparer.Default.Compare(
((Item)left).MspName, ((Item)right).MspName);
}
else
throw new ArgumentException("One of the object is not an
Item");
}
}

//Tony
"Jon Skeet [C# MVP]" <sk***@pobox.comskrev i meddelandet
news:cc**********************************@27g2000h sf.googlegroups.com...
On Jun 17, 9:18 am, "Tony" <johansson.anders...@telia.comwrote:
I'm reading in a book and this can't be correct it says.
"Objects passed to Comparer.Compare() are checked to see if they support
IComparable.
If they do, then that implementation is used"

One thing to note is that most of the time you should now be using the
generic Comparer<Tclass and in particular Comparer<T>.Default.
Assume I have a collection of Item(s) in an ArrayList
This class called Item support the IComparable interface which contains
the
CompareTo method
so this method is impemented in class Item.

Now I can sort in the way that this CompareTo is implemented.

Now assume I want to be able to sort the collection of item(s) in
another
way then this CompareTo is implementet
so I create an helper class which implement the IComparer interface
which
contains method Compare.

So far so good - but at that point you don't use the Comparer class,
you just pass an instance of your IComparer implementation into
whatever sorting method you're using.
So not to my question when object of type Item is passed to the Compare
method that implementation
is used of course not the implementation that exist for the IComparable.

The quote you gave specified part of the implementation of
Comparer.Compare. If you're not calling Comparer.Compare, then the
quote is irrelevant. Why would you call Comparer.Compare if you want
to use a custom IComparer implementation?

Perhaps it would help if you'd provide a short but complete example,
and ask what the behaviour is and why for a specific method call.

Jon

Jun 27 '08 #4
That is *not* a complete program; it has no "Main", so does nothing
(not even compile...).

Re your question - the only things you pass to
Comparer.Default.Compare(...) are two ints (the two Steelgrade
properties); I fully expect that Comparer will give the correct answer
for comparing two ints, but there is no reason to expect it to call
your IComparable implementation - it isn't comparing Item, it is
comparing ints - it will use the Int32.Compare method.

Marc
Jun 27 '08 #5
(white lie - you also pass two strings, but this will behave similarly)
Jun 27 '08 #6
On Jun 17, 10:04 am, "Tony" <johansson.anders...@telia.comwrote:
Here I have not Complete program enough to be able to answer my question.
Here again I pass an object to this Comparer.Compare() although there is an
Default in between.
Well, your code is really making things confusing by having an
ItemComparer.Default as well as using Comparer.Default.
Objects passed to Comparer.Compare() are checked to see if they support
IComparable.
If they do, then that implementation is used"

Below when I pass object to this Comparer.Default.Compare I don't use the
implementation from
IComparable that the text above is claiming I use whatever relevent code I
want.?
The call to Comparer.Default.Compare with the two different Steelgrade
values will use the fact that int implements IComparable. That's all
that the text is claiming. The rest of your code isn't a call to
Comparer.Compare, it's an implementation of IComparer.Compare. There's
a huge difference.

Mind you, your code would be significantly simpler if you just called
Compare directly, preferrably avoiding all those casts:

public int Compare(object left, object right)
{
// TODO: optimise for left == right, and consider cases
// where one side or other is null
Item leftItem = left as Item;
Item rightItem = right as Item;
if (leftItem == null || rightItem == null)
{
throw new ArgumentException("One of the objects is not an
Item");
}
if (leftItem.Steelgrade != rightItem.Steelgrade)
{
return leftItem.Steelgrade.CompareTo(rightItem.Steelgrade );
}
// TODO: Consider what kind of string comparison you want (culture/
ordinal/case sensitive)
return leftItem.MspName.CompareTo(rightItem.MspName);
}
So what the text is claiming must be completely nonsens.!
No it's not. Comparer.Compare will use the IComparable.CompareTo
implementation. But other implementations of IComparer are free to do
what they want.

It seems to me that you're not distinguishing between the interface
(IComparer) and *one* implementation (Comparer).

Jon
Jun 27 '08 #7
Here's a Main that demonstrates it working just fine... you'll have to
forgive some C# 3 initializer syntax (easy enough to see what it does,
though):

class Program
{
static void Main()
{
ArrayList list = new ArrayList();
list.Add(new Item { HeatNumber = 1, Steelgrade = 4, MspName =
"def" });
list.Add(new Item { HeatNumber = 3, Steelgrade = 4, MspName =
"ghi" });
list.Add(new Item { HeatNumber = 1, Steelgrade = 2, MspName =
"abc" });
list.Add(new Item { HeatNumber = 2, Steelgrade = 1, MspName =
"jkl" });
Console.WriteLine("Using custom sort (HeatNumber, MspName)");
list.Sort();
foreach (Item item in list)
{
Console.WriteLine("{0}: hn: {1}, sg: {2}", item.MspName,
item.HeatNumber, item.Steelgrade);
}
Console.WriteLine("Using custom sort (Steelgrade, MspName)");
list.Sort(ItemComparer.Default);
foreach (Item item in list)
{
Console.WriteLine("{0}: hn: {1}, sg: {2}", item.MspName,
item.HeatNumber, item.Steelgrade);
}
}
}

Jun 27 '08 #8
(sorry, copy/paste - first is the default sort using the item's
IComparable implementation)
Jun 27 '08 #9
Hello!

You say that your code would be significantly simpler if you just called
Compare directly, preferrably avoiding all those casts:
You you mean as the code prove instead CompareTo(...) I assume

//Tony

"Jon Skeet [C# MVP]" <sk***@pobox.comskrev i meddelandet
news:80**********************************@s50g2000 hsb.googlegroups.com...
On Jun 17, 10:04 am, "Tony" <johansson.anders...@telia.comwrote:
Here I have not Complete program enough to be able to answer my
question.
Here again I pass an object to this Comparer.Compare() although there is
an
Default in between.

Well, your code is really making things confusing by having an
ItemComparer.Default as well as using Comparer.Default.
>Objects passed to Comparer.Compare() are checked to see if they
support
IComparable.
If they do, then that implementation is used"
Below when I pass object to this Comparer.Default.Compare I don't use
the
implementation from
IComparable that the text above is claiming I use whatever relevent code
I
want.?

The call to Comparer.Default.Compare with the two different Steelgrade
values will use the fact that int implements IComparable. That's all
that the text is claiming. The rest of your code isn't a call to
Comparer.Compare, it's an implementation of IComparer.Compare. There's
a huge difference.

Mind you, your code would be significantly simpler if you just called
Compare directly, preferrably avoiding all those casts:

public int Compare(object left, object right)
{
// TODO: optimise for left == right, and consider cases
// where one side or other is null
Item leftItem = left as Item;
Item rightItem = right as Item;
if (leftItem == null || rightItem == null)
{
throw new ArgumentException("One of the objects is not an
Item");
}
if (leftItem.Steelgrade != rightItem.Steelgrade)
{
return leftItem.Steelgrade.CompareTo(rightItem.Steelgrade );
}
// TODO: Consider what kind of string comparison you want (culture/
ordinal/case sensitive)
return leftItem.MspName.CompareTo(rightItem.MspName);
}
So what the text is claiming must be completely nonsens.!

No it's not. Comparer.Compare will use the IComparable.CompareTo
implementation. But other implementations of IComparer are free to do
what they want.

It seems to me that you're not distinguishing between the interface
(IComparer) and *one* implementation (Comparer).

Jon

Jun 27 '08 #10
On Jun 17, 11:17 am, "Tony" <johansson.anders...@telia.comwrote:
You say that your code would be significantly simpler if you just called
Compare directly, preferrably avoiding all those casts:
You you mean as the code prove instead CompareTo(...) I assume
Sorry, yes, I meant CompareTo.

Jon
Jun 27 '08 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: Tom | last post by:
Has anyone ever seen a IComparer for floats the returns magnitude. i.e. instead of returning -1, it would return -5. To let you know HOW different the two numbers are. obviously for int it is a -...
3
by: Cybertof | last post by:
Hello, Could someone please explain me the difference between the 2 interfaces IComparable and IComparer ? In which cases use one or the other ? Are they dedicated to own classes or built-in...
4
by: CodeRazor | last post by:
Hi, I want to retrieve a sorted list of files, ordered by LastWriteTime. I know I can implement IComparer, but I don't know how or what this means. I know a sortedlist has objects and keys and...
3
by: RJN | last post by:
Hi I have a user defined data type which implements IComparable interface and has an implementation for the CompareTo method. Public Class MyDataType Implements IComparable --Private...
10
by: INeedADip | last post by:
I am trying to use a generic (reflection) IComparer class to sort a generic list but I get the error: Unable to cast object of type 'GenericComparer' to type 'System.Collections.Generic.Icomparer...
4
by: Irfan | last post by:
hi, I am trying to arrange a CollectionOfCars in increasing order of their X-Cordinate location. CollectionOfCars is a generic collection. Dim CollectionOfCars as new list(of Car) Here is...
2
by: ckarbass | last post by:
I am testing a comparer class that implements IComparer. The comparer constructor takes as arguments a property field which can take on lets say roughly fifteen values. It also takes two other...
3
by: QDL | last post by:
Hello everyone, I have a very simple question about arrays I have an array of Processes objects (retrieved using Process.GetProcesses()). I want to sort them descending on the WorkingSet size. ...
6
by: Tony | last post by:
Hello! My first question: I just can't figure out what is the usefulness of Comparer.Default.Compare(somestring1, somestring2); because I can just the same use...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.