Sorting


T

Tony Johansson

Hi!

This is just for understanding I know about generics.

If I have for example this ArrayList
ArrayList list = new ArrayList();
and add some int's(Int32) to this list and then use the sort method like
this
list.Sort();
then the default Comparer class is used which is the default implementation
of the IComparer interface.

Question number 1:
Now to my question is there any methods or property in the int32 structure
that is used when I use the Sort method
in the ArrayList ?
I mean if there are any requirements on the int's structure when you use the
Comparer class that implement the Compare method.

Here is the header for the struct definition for int32 and as I can see here
is there no interface that is used
when I do list.Sort using the Comparer class.
public struct Int32 : IComparable, IFormattable,
IConvertible, IComparable<int>, IEquatable<int>
{...}


Question number 2:
So as I understand this the Sort method in ArrayList just call the method
Compare in the Comparer class
Comparer.Compare(object x, object y )
So the actual datatype int's in the ArrayList is passed as argument to the
Compare method in the Comparer class.

//Tony
 
Ad

Advertisements

G

Göran Andersson

Tony said:
Hi!

This is just for understanding I know about generics.

If I have for example this ArrayList
ArrayList list = new ArrayList();
and add some int's(Int32) to this list and then use the sort method like
this
list.Sort();
then the default Comparer class is used which is the default implementation
of the IComparer interface.

Question number 1:
Now to my question is there any methods or property in the int32 structure
that is used when I use the Sort method
in the ArrayList ?
I mean if there are any requirements on the int's structure when you use the
Comparer class that implement the Compare method.

Yes, when comparing two items the default comparer looks for the
IComparable interface in the first item and calls the CompareTo method
using the other item.
Here is the header for the struct definition for int32 and as I can see here
is there no interface that is used
when I do list.Sort using the Comparer class.
public struct Int32 : IComparable, IFormattable,
IConvertible, IComparable<int>, IEquatable<int>
{...}

Yes, the IComparable interface is there.
Question number 2:
So as I understand this the Sort method in ArrayList just call the method
Compare in the Comparer class
Comparer.Compare(object x, object y )
So the actual datatype int's in the ArrayList is passed as argument to the
Compare method in the Comparer class.

The items to compare are passed as object references to the Compare
method. The Compare method tries to cast the first item to IComparable,
thus getting the Int32 specific implementation of the CompareTo method.
This way the first item is effectively cast to Int32, but the second
item is sent as an object reference to the CompareTo method, which then
has to check it's type to see if it can cast it to Int32.

If you use a List<int> instead of an ArrayList all this looks
differently. Then the Sort method only determines the comparer to use
once, instead of for each item to compare. It also looks for the
IComparable<int> implementation, so the comparisons will be done on
typed data so that it doesn't have to do null reference checks, type
examination and unboxing before the actual comparison.
 
T

Tony Johansson

Göran Andersson said:
Yes, when comparing two items the default comparer looks for the
IComparable interface in the first item and calls the CompareTo method
using the other item.


Yes, the IComparable interface is there.


The items to compare are passed as object references to the Compare
method. The Compare method tries to cast the first item to IComparable,
thus getting the Int32 specific implementation of the CompareTo method.
This way the first item is effectively cast to Int32, but the second item
is sent as an object reference to the CompareTo method, which then has to
check it's type to see if it can cast it to Int32.

If you use a List<int> instead of an ArrayList all this looks differently.
Then the Sort method only determines the comparer to use once, instead of
for each item to compare. It also looks for the IComparable<int>
implementation, so the comparisons will be done on typed data so that it
doesn't have to do null reference checks, type examination and unboxing
before the actual comparison.

Hi

What you say doesn't match what is says in the book that I'm reading and I
have also used the Red Gats .NET reflection to look into the code.

The book is saying the following.
"The ArrayList supports a method to sort a collection's items. To sort items
within an ArrayList, simply call Sort
method of the ArrayList like so.
ArrayList list = new ArrayList();
//add for example int's items to the list
list.Sort();

The Sort method works by using the Comparer class to do the comparision.
The Comparer class is a default implementation
that supports the IComparer interface. This interface dictates that you
implement a single method called Compare that takes two objects(for example
a and b) and returns an integer that represent the result of the
comarision."

What is correct in this matter ?

//Tony
 
K

Konrad Neitzel

Hi Tony!

Of course it matches.

The book tells you, that ArrayList is using the class Comparer to compare 2
objects (With interface IComparer!)

And the additional information was simple:
Comparer must be able to compare the 2 objects. But it is simply not
possible without help of the developer. The Comparer simply requires that
the objects implements ICompareable.

So the conclusion is: the Int32 needs to implement the ICompareable
interface. An integer wants to be compared with some other object. An
integer does not want to compare 2 other objects with each other (IComparer
Interface)

Please have a closer look at the different Classes / Interfaces inside the
MSDN Library. There you find all information that you need.

So inside the description of the compare Function of Comparer you find the
following information:

If a implements IComparable, then a. CompareTo (b) is returned; otherwise,
if b implements IComparable, then the negated result of b. CompareTo (a) is
returned.

Comparing nullNothingnullptra null reference (Nothing in Visual Basic) with
any type is allowed and does not generate an exception when using
IComparable. When sorting, nullNothingnullptra null reference (Nothing in
Visual Basic) is considered to be less than any other object.

String comparisons might have different results depending on the culture.
For more information on culture-specific comparisons, see the
System.Globalization namespace and Encoding and Localization.

Konrad
 
T

Tony Johansson

Konrad Neitzel said:
Hi Tony!

Of course it matches.

The book tells you, that ArrayList is using the class Comparer to compare
2 objects (With interface IComparer!)

And the additional information was simple:
Comparer must be able to compare the 2 objects. But it is simply not
possible without help of the developer. The Comparer simply requires that
the objects implements ICompareable.

So the conclusion is: the Int32 needs to implement the ICompareable
interface. An integer wants to be compared with some other object. An
integer does not want to compare 2 other objects with each other
(IComparer Interface)

Please have a closer look at the different Classes / Interfaces inside the
MSDN Library. There you find all information that you need.

So inside the description of the compare Function of Comparer you find the
following information:

If a implements IComparable, then a. CompareTo (b) is returned; otherwise,
if b implements IComparable, then the negated result of b. CompareTo (a)
is returned.

Comparing nullNothingnullptra null reference (Nothing in Visual Basic)
with any type is allowed and does not generate an exception when using
IComparable. When sorting, nullNothingnullptra null reference (Nothing in
Visual Basic) is considered to be less than any other object.

String comparisons might have different results depending on the culture.
For more information on culture-specific comparisons, see the
System.Globalization namespace and Encoding and Localization.

Konrad

Where did you find this piece of code.
If a implements IComparable, then a. CompareTo (b) is returned; otherwise,
if b implements IComparable, then the negated result of b. CompareTo (a) is
returned.

//Tony
 
P

Peter Duniho

Tony said:
Konrad Neitzel said:
[...]
Please have a closer look at the different Classes / Interfaces inside the
MSDN Library. There you find all information that you need.

So inside the description of the compare Function of Comparer you find the
following information:

If a implements IComparable, then a. CompareTo (b) is returned; otherwise,
if b implements IComparable, then the negated result of b. CompareTo (a)
is returned.

[...]

Where did you find this piece of code.
If a implements IComparable, then a. CompareTo (b) is returned; otherwise,
if b implements IComparable, then the negated result of b. CompareTo (a) is
returned.

As his post says, he's not talking about code. He's talking about the
documentation:
http://msdn.microsoft.com/en-us/library/system.collections.comparer.compare.aspx

Pete
 
Ad

Advertisements

K

Konrad Neitzel

Hi Tony!

Tony Johansson said:
"Konrad Neitzel" <[email protected]> skrev i meddelandet
Where did you find this piece of code.
If a implements IComparable, then a. CompareTo (b) is returned; otherwise,
if b implements IComparable, then the negated result of b. CompareTo (a)
is
returned.

I always check the description of classes and methods in my localy installed
MSDN Library. I find the search in there much better when you really just
want to get the description of the class or so. The search function of the
MSDN web simply provides much more than I am interested in.

If you do not have such an installation: I would recommend that you download
and install it. Inside the MSDN Library you can simply go to the indec tab
and enter "Comparer" there. Then you will see something like
Comparer class
- about Comparer class
- all members

Just all members and in the list of members you can easily click on the
table entry of the Compare Method.

The comment came from the Remark field of the description of that method.

But of course: All this is available online, too. I just looked it up and it
is:
http://msdn.microsoft.com/en-us/library/system.collections.comparer.compare.aspx

With kind regards,

Konrad
 
T

Tony Johansson

Konrad Neitzel said:
Hi Tony!




I always check the description of classes and methods in my localy
installed MSDN Library. I find the search in there much better when you
really just want to get the description of the class or so. The search
function of the MSDN web simply provides much more than I am interested
in.

If you do not have such an installation: I would recommend that you
download and install it. Inside the MSDN Library you can simply go to the
indec tab and enter "Comparer" there. Then you will see something like
Comparer class
- about Comparer class
- all members

Just all members and in the list of members you can easily click on the
table entry of the Compare Method.

The comment came from the Remark field of the description of that method.

But of course: All this is available online, too. I just looked it up and
it is:
http://msdn.microsoft.com/en-us/library/system.collections.comparer.compare.aspx

With kind regards,

Konrad
Hi!

I just wonder if I use the Red Gate's Reflector and look all the way
from I do the Sort on an ArrayList I can't see anywhere where they do
anything like the below
If a implements IComparable, then a. CompareTo (b) is returned; otherwise,
if b implements IComparable, then the negated result of b. CompareTo (a)
is returned.
Here is the version on mscorlib that I look at when using the Red Gate's
Reflector
Location: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorlib.dll
Name: mscorlib, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089
Type: Library


Does anyone have anykind of explanation to this.

//Tony
 
K

Konrad Neitzel

Hi Tony!

I just wonder if I use the Red Gate's Reflector and look all the way
from I do the Sort on an ArrayList I can't see anywhere where they do
anything like the below
If a implements IComparable, then a. CompareTo (b) is returned; otherwise,
if b implements IComparable, then the negated result of b. CompareTo (a)
is returned.
Here is the version on mscorlib that I look at when using the Red Gate's
Reflector
Location: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorlib.dll
Name: mscorlib, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089
Type: Library

As I said: I just checked the description inside the MSDN Library. Nothing
else. I just believe, that the developers are no liars so I can trust the
documentation. :).

I have no idea, what you are exactly looking at. Normaly there should be no
requirement to look into the IL Code or so. It can be a nice and challenging
thing but at least for beginners it is nothing that they should do (in my
eyes). And it normaly does not help at all to get "the big picture". And
from your first question it seems that you are still trying to get the big
picture of the stuff that is happening.

So to get you the big picture what is happening:
- ArrayList offers a Sort() Function
- Inside Sort() there is a requirement to Compare 2 Objects that are inside.
For this, an instance of Comparer is used.
- Comparer.Compare(Object a, Object b) is using the ICompareable interface
of a or b if they support it. Also String compares are done / can be done.

==> So if you want to Sort Objects in an ArrayList: Make sure that they are
either Strings or Objects that implement ICompareable.
==> That is the reason that your Int32 struct is implementing the
ICompareable.

Or what is important for your 070-536 exam:
- IComparer defines a Function Compare(Object a, Object b) that can be used
to compare other objects. (So for example you could write an
UniversalStringComparere that simply compares the ToString() results of the
2 Objects.)
- ICompareable defines a Function CompareTo(Object b) which gives an Object
the ability to compare it to other objects.

Did this help a little to clarify the issue? Or did that confuse you even
more?

Konrad
 
T

Tony Johansson

Hi!

No it was good and I understand it but I would
even though be able to see the code using the Red Gate's .NET Reflector.

Hopefully somebody might know why I can't see this in the Red Gate's .NET
Reflector

//Tony
 
P

Peter Duniho

Tony said:
I just wonder if I use the Red Gate's Reflector and look all the way
from I do the Sort on an ArrayList I can't see anywhere where they do
anything like the below
If a implements IComparable, then a. CompareTo (b) is returned; otherwise,
if b implements IComparable, then the negated result of b. CompareTo (a)
is returned.
Here is the version on mscorlib that I look at when using the Red Gate's
Reflector
Location: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorlib.dll
Name: mscorlib, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089
Type: Library


Does anyone have anykind of explanation to this.

Yes. It appears to be a bug.

The documentation _and_ the exception thrown both indicate that only one
of the comparands need to implement IComparable. But the
implementation, visible either through Reflector or from the original
source code, clearly supports comparison only if the _first_ operand "a"
implements IComparable.

I've reported this as a .NET bug, since it seems clear to me from the
documentation and exception text that the intent was always for it to
work if _either_ comparand implemented IComparable, and because there's
no good reason for the comparison to not be symmetrical.

Anyone who has an opinion regarding whether this is an important bug to
fix should review the report and add your vote for the importance. You
can review the bug report here:
https://connect.microsoft.com/Visua...od-only-checks-first-argument-for-icomparable

Pete
 
Ad

Advertisements

P

Peter Duniho

Konrad said:
Hi Tony!

I just wonder if I use the Red Gate's Reflector [...]

As I said: I just checked the description inside the MSDN Library.
Nothing else. I just believe, that the developers are no liars so I can
trust the documentation. :).

Documentation != implementation.

It's well and good to start with the documentation. But it's not the
final word. Only the compiled, executing code is the final word.
I have no idea, what you are exactly looking at.

I think Tony's post was pretty clear about what he's looking at. He's
using Reflector to examine the actual implementation.
Normaly there should be
no requirement to look into the IL Code or so. It can be a nice and
challenging thing but at least for beginners it is nothing that they
should do (in my eyes).

Yes, normally. But, if there's a bug, or in fact any discrepancy
between the observed behavior and the documented behavior in .NET, it
can be very useful as a way to understand that issue better.

As for whether it's appropriate for beginners, since Reflector can
disassemble IL back to C# code, there's no need to actually know IL at
all to make use of the utility. Nor would that be relevant in any case,
since regardless Tony did correctly examine the actual .NET
implementation of the code he's asking about.
And it normaly does not help at all to get "the
big picture". And from your first question it seems that you are still
trying to get the big picture of the stuff that is happening.

Your sentiment is well-meaning, but I think in this case ill-placed. In
particular, Tony's question is perfectly valid, beginner or not. Also,
his English isn't perfect and so it can sometimes appear he doesn't
understand things as well as he actually does. He's actually quite a
bit more astute than you might realize. :)
So to get you the big picture what is happening:
- ArrayList offers a Sort() Function
Yes.

- Inside Sort() there is a requirement to Compare 2 Objects that are
inside. For this, an instance of Comparer is used.
Yes.

- Comparer.Compare(Object a, Object b) is using the ICompareable
interface of a or b if they support it.

No. The documentation claims that's what happens, but it's not actually
what happens. (By the way, the name of the interface is "IComparable",
not "ICompareable" :) ).

Now, in my opinion, in practice this issue really shouldn't come up
much, if at all.

For example: if any element of an Array implements IComparable, then ALL
elements of the Array ought to, especially if you're going to sort the
elements. After all, unless you have only one object that fails to
implement IComparable in the array, you have no way to ensure that the
sorting algorithm isn't going to need to compare two different objects,
neither of which implement IComparable.

And that doesn't even take into account the issue that it's not
sufficient for IComparable to be implemented. The implementation would
have to support valid comparisons between objects of different types for
the above scenario to actually work.

In reality, the Array will almost certainly contain elements all of the
same type, so if any element implements IComparable, all will. And most
of the exceptions to that situation would be when the Array contains
elements of the same base type where the IComparable interface is
implemented, and where that implementation is compatible with comparing
objects of different types. The latter scenario being quite rare indeed
(most comparison implementations really only work if the two objects are
exactly the same type).

But, the fact of the matter is, the documentation does not in fact match
the actual implementation.

Pete
 
K

kndg

Yes. It appears to be a bug.

Agreed.

POC:

class Base
{
public readonly int Data;

public Base(int data)
{
Data = data;
}
}

class A : Base, IComparable
{
public A(int data)
: base(data)
{
}

public int CompareTo(object obj)
{
var target = obj as Base;

if (target != null)
return Data.CompareTo(target.Data);

throw new InvalidOperationException();
}
}

class B : Base
{
public B(int data)
: base(data)
{
}
}

class Program
{
static void Main(string[] args)
{
var a5 = new A(5);
var b3 = new B(3);

try
{
Comparer.Default.Compare(a5, b3);
Comparer.Default.Compare(b3, a5);
}
catch (Exception e)
{
Console.WriteLine(e.GetType());
Console.WriteLine(e.Message);
}

Console.ReadKey();
}
}

Documentation is true only for .NET 1.1 (I had checked its mscorlib.dll
through reflector). I'm not sure for .Net 1.0 though.
..Net 4.0 beta same bug.

I'll vote it to be fixed.

Regards.
 
T

Tony Johansson

Peter Duniho said:
Yes. It appears to be a bug.

The documentation _and_ the exception thrown both indicate that only one
of the comparands need to implement IComparable. But the implementation,
visible either through Reflector or from the original source code, clearly
supports comparison only if the _first_ operand "a" implements
IComparable.

I've reported this as a .NET bug, since it seems clear to me from the
documentation and exception text that the intent was always for it to work
if _either_ comparand implemented IComparable, and because there's no good
reason for the comparison to not be symmetrical.

Anyone who has an opinion regarding whether this is an important bug to
fix should review the report and add your vote for the importance. You
can review the bug report here:
https://connect.microsoft.com/Visua...od-only-checks-first-argument-for-icomparable

Pete

Hi

Again I just wonder when I use the Red Gate's Reflector and look all the way
from where I do the Sort on an ArrayList I can't see anywhere a sight of the
IComparable.
Here is the version on mscorlib that I look at when using the Red Gate's
Reflector
Location: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorlib.dll
Name: mscorlib, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089
Type: Library

Here is the code copied from the Red Gate's Reflector and in this code is
not a sight of any IComparable only IComparer
So why is it not any IComparable here.
ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
public static void Sort(Array keys, Array items, int index, int length,
IComparer comparer)
{
if (keys == null)
{
throw new ArgumentNullException("keys");
}
if ((keys.Rank != 1) || ((items != null) && (items.Rank != 1)))
{
throw new
RankException(Environment.GetResourceString("Rank_MultiDimNotSupported"));
}
if ((items != null) && (keys.GetLowerBound(0) !=
items.GetLowerBound(0)))
{
throw new
ArgumentException(Environment.GetResourceString("Arg_LowerBoundsMustMatch"));
}
if ((index < keys.GetLowerBound(0)) || (length < 0))
{
throw new ArgumentOutOfRangeException((length < 0) ? "length" :
"index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if (((keys.Length - (index - keys.GetLowerBound(0))) < length) ||
((items != null) && ((index - items.GetLowerBound(0)) > (items.Length -
length))))
{
throw new
ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
}
if ((length > 1) && (((comparer != Comparer.Default) && (comparer !=
null)) || !TrySZSort(keys, items, index, (index + length) - 1)))
{
object[] objArray = keys as object[];
object[] objArray2 = null;
if (objArray != null)
{
objArray2 = items as object[];
}
if ((objArray != null) && ((items == null) || (objArray2 != null)))
{
new SorterObjectArray(objArray, objArray2,
comparer).QuickSort(index, (index + length) - 1);
}
else
{
new SorterGenericArray(keys, items, comparer).QuickSort(index,
(index + length) - 1);
}
}
}

//Tony
 
K

kndg

kndg said:
Does anyone have anykind of explanation to this.

Yes. It appears to be a bug.

Agreed.

POC: [...]

FYI: I already posted code in my bug report. :)

Hahaha... I didn't check your bug report before posting.
Just voted.
[...]
Documentation is true only for .NET 1.1

Really? Now THAT is bizarre. This used to work, and they broke it? Geez…

Maybe, they have a reason that we are not aware...
Mono also suffers the same bug. Hmm...
 
Ad

Advertisements

P

Peter Duniho

Tony said:
Again I just wonder when I use the Red Gate's Reflector and look all the way
from where I do the Sort on an ArrayList I can't see anywhere a sight of the
IComparable.

Well, maybe Konrad was right about whether you can be trusted with
Reflector. :)

(Just kidding)
Here is the version on mscorlib that I look at when using the Red Gate's
Reflector
Location: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorlib.dll
Name: mscorlib, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089
Type: Library

Here is the code copied from the Red Gate's Reflector and in this code is
not a sight of any IComparable only IComparer
So why is it not any IComparable here.

You saw IComparer. Why didn't you bother to look into the
_implementation_ of IComparer being used? What's the point of drilling
down into a stack trace, if you're not actually going to go all the way
to the end?

Hint: unless you provide your own Comparer interface, you get the
default implementation, which checks one of the comparands (but not
both…see my bug report) for an implementation of IComparable.

_That_ is where you'd see IComparable. The Array.Sort() method has no
need to know about IComparable, because it delegates that work to the
IComparer implementation being used.

If you want to see the method being used, where IComparable is actually
used, look at the the System.Collections.Comparer.Compare() method, just
as my bug report describes.

Pete
 
K

Konrad Neitzel

Hi Peter!

Documentation != implementation.

Of course, but normaly it is ok to trust the MSDN documentation and that is
the first start. At least in my eyes all this stuff only starts when you
find something is not working.
(e.g. ActiveDirectory implementation inside the Framework and simple
MemoryLeaks in the used caching! Maybe I will post something about that
because a bug report could on that could be nice, too.)
It's well and good to start with the documentation. But it's not the
final word. Only the compiled, executing code is the final word.

You are right with this point. And you are also right that I should not do
any conclusion without knowing facts.
I think Tony's post was pretty clear about what he's looking at. He's
using Reflector to examine the actual implementation.

Yes. I think I was to stuck on the "Where did you find this piece of code"
part. I didn't look at any code and I simply tried to explain that again. My
error was simply that I didn't see, that he was much further than I thought.
Your sentiment is well-meaning, but I think in this case ill-placed. In
particular, Tony's question is perfectly valid, beginner or not. Also,
his English isn't perfect and so it can sometimes appear he doesn't
understand things as well as he actually does. He's actually quite a bit
more astute than you might realize. :)

Yes, you are right. I simply missunderstood his posting.
No. The documentation claims that's what happens, but it's not actually
what happens.
Yes. And the good thing is, that I spend some time on Reflector now, too. So
at least I learned something again :)
(By the way, the name of the interface is "IComparable", not
"ICompareable" :) ).
Of course. My bad to make it a compare able thing :)

Thank you for putting me right.

With kind regards,

Konrad
 
G

Göran Andersson

Peter said:
Yes. It appears to be a bug.

The documentation _and_ the exception thrown both indicate that only one
of the comparands need to implement IComparable. But the
implementation, visible either through Reflector or from the original
source code, clearly supports comparison only if the _first_ operand "a"
implements IComparable.

I've reported this as a .NET bug, since it seems clear to me from the
documentation and exception text that the intent was always for it to
work if _either_ comparand implemented IComparable, and because there's
no good reason for the comparison to not be symmetrical.

Anyone who has an opinion regarding whether this is an important bug to
fix should review the report and add your vote for the importance. You
can review the bug report here:
https://connect.microsoft.com/Visua...od-only-checks-first-argument-for-icomparable


Pete

When the comparer is used for sorting, the only difference would be that
you could have a single item in the collection that doesn't implement
IComparable, but then all other items in the collection would need to
know how to compare themselves to that item. If you have more than one,
the sorting algorithm may end up trying to compare them and fail.

The only scenario that I can come up with where this would happen, is if
you have two custom classes (/structs) where one of them implements
IComparable to compare itself to the same class and to the other class.

So, where probably just looking at a documentation adjustment here. :)
 
Ad

Advertisements

P

Peter Duniho

Göran Andersson said:
When the comparer is used for sorting, the only difference would be that
you could have a single item in the collection that doesn't implement
IComparable, but then all other items in the collection would need to
know how to compare themselves to that item. If you have more than one,
the sorting algorithm may end up trying to compare them and fail.

Which I already pointed out in a previous reply. But yes, obviously I
agree, for _sorting_. But IComparable isn't necessarily used only for
sorting.
The only scenario that I can come up with where this would happen, is if
you have two custom classes (/structs) where one of them implements
IComparable to compare itself to the same class and to the other class.

By definition that's the only scenario that would apply. But that
offers no guidance as to how often that's a legitimate scenario, nor as
to why it would be reasonable for the Comparer class to treat the
comparands asymmetrically.
So, where probably just looking at a documentation adjustment here. :)

I disagree. At the very least, the asymmetric behavior is a bug, and so
Comparer ought to either insist that both comparands implement
IComparable, or it should accept both if only one implements it.

For it to accept the situation where only one implements IComparable,
but to insist that that one always be the first comparand, is IMHO bad
design at best, and according to both the documentation _and_ the
exception thrown is actually a bug.

Personally, I think that it only makes sense to allow either, but not
require both, comparands to implement IComparable. Even if both
implement it, you have no guarantee that both are the same class, with
the same implementation of IComparable, so requiring both to implement
it doesn't actually guarantee a symmetric implementation anyway.

So it might as well just look for the first comparand that implements
IComparable and call that.

That said, you should feel free to add your own comments to the bug
report and vote as you see fit.

Pete
 

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