[MC++] ArrayList::Sort() behavior

M

Marcus Kwok

I wrote a little test program to demonstrate what may be a
misunderstanding on my part in the behavior of ArrayList::Sort().

I defined a class (Test) that has two data members: a System::String*
(name) and a double value. Test implements IComparable, so I made the
CompareTo() function sort first by name, then by the value of the
double.

When I run the code below, it sorts by name correctly, but it does not
sort correctly the items with the same name.


#using <mscorlib.dll>

using namespace System;
using namespace System::Collections;

public __gc class Test : public IComparable {
public:
Test(System::String* name, double d)
: name_(name)
, d_(d)
{ }

Int32 CompareTo(Object* obj)
{
if (obj->GetType() == __typeof(Test)) {
Test* t = dynamic_cast<Test*>(obj);
return (name_->Equals(t->name_) ? d_ < t->d_ : name_->CompareTo(t->name_));
}
throw new ArgumentException("object is not a Test");
}

System::String* ToString()
{
return String::Concat(name_, S": ", __box(d_));
}

private:
System::String* name_;
double d_;
};

int main()
{
ArrayList* array = new ArrayList;

array->Add(new Test(S"Me", 1.0));
array->Add(new Test(S"A", 0.0));
array->Add(new Test(S"Me", 2.0));
array->Add(new Test(S"B", 0.0));
array->Add(new Test(S"Me", 3.0));
array->Add(new Test(S"C", 0.0));
array->Add(new Test(S"Me", 4.0));

Console::WriteLine(S"Original:");
for (int i = 0; i < array->Count; ++i) {
Console::WriteLine(array->Item);
}
Console::WriteLine();

for (int i = 0; i < 4; ++i) {
array->Sort();
Console::WriteLine(String::Concat(S"After Sort() #", __box(i + 1)->ToString(), ":"));
for (int i = 0; i < array->Count; ++i) {
Console::WriteLine(array->Item);
}
Console::WriteLine();
}

return 0;
}


Output:
Original:
Me: 1
A: 0
Me: 2
B: 0
Me: 3
C: 0
Me: 4

After Sort() #1:
A: 0
B: 0
C: 0
Me: 4
Me: 3
Me: 2
Me: 1

After Sort() #2:
A: 0
B: 0
C: 0
Me: 2
Me: 1
Me: 4
Me: 3

After Sort() #3:
A: 0
B: 0
C: 0
Me: 4
Me: 3
Me: 2
Me: 1

After Sort() #4:
A: 0
B: 0
C: 0
Me: 2
Me: 1
Me: 4
Me: 3
 
M

Marcus Kwok

Marcus Kwok said:
I defined a class (Test) that has two data members: a System::String*
(name) and a double value. Test implements IComparable, so I made the
CompareTo() function sort first by name, then by the value of the
double.

Int32 CompareTo(Object* obj)
{
if (obj->GetType() == __typeof(Test)) {
Test* t = dynamic_cast<Test*>(obj);
return (name_->Equals(t->name_) ? d_ < t->d_ : name_->CompareTo(t->name_));

Nevermind, I found the error: I needed to box the doubles and call
CompareTo() on those:

return (name_->Equals(t->name_) ? __box(d_)->CompareTo(__box(t->d_)) : name_->CompareTo(t->name_));
 

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