what is the wrong with this implementation of Comparable<T>

T

Tony Johansson

Hello!

I have the following simple program below.
What is the problem when I get runtime error for
"Failed to compare two elements in the array ?"

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace ConsoleApplication15
{
class Program
{
static void Main(string[] args)
{
ArrayList list = new ArrayList();
list.Add(new Person("tony", 13));
list.Add(new Person("olle", 23));
list.Add(new Person("stina", 53));
list.Add(new Person("august", 3));
list.Add(new Person("roland", 33));

foreach (Person pers in list)
Console.WriteLine(pers.Age);

list.Sort();
foreach (Person pers in list)
Console.WriteLine(pers.Age);
}
}

public class Person : IComparable<Person>
{
string name;
int age;

public Person(string lname, int lage)
{
name = lname;
age = lage;
}

public int Age
{
set {age = value;}
get {return age; }
}

public int CompareTo(Person other)
{
return this.Age - other.Age;
}
}
}


//Tony
 
J

Jeroen Mostert

Tony said:
I have the following simple program below.
What is the problem when I get runtime error for
"Failed to compare two elements in the array ?"

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace ConsoleApplication15
{
class Program
{
static void Main(string[] args)
{
ArrayList list = new ArrayList();

You're using ArrayList...
public class Person : IComparable<Person>

But you fail to implement the non-generic interface IComparable.

If you use List<Person> instead of ArrayList (which is a good idea), the
problem disappears, but you should also implement the non-generic
counterpart to IComparable said:
public int CompareTo(Person other)
{
return this.Age - other.Age;
}

This implementation is not correct: you must check for the case that "other"
is null (and return a positive value in that case).
 
T

Tony Johansson

Hello!

Yes I noticed that my runtime error disapperar when I used List<T> instad of
ArrayList.
Yes I also know that it's a better solution to use List<T> instad of
ArrayList.

But I just want to find out what is causing the error when I use the
ArrayList?

//Tony


Jeroen Mostert said:
Tony said:
I have the following simple program below.
What is the problem when I get runtime error for
"Failed to compare two elements in the array ?"

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace ConsoleApplication15
{
class Program
{
static void Main(string[] args)
{
ArrayList list = new ArrayList();

You're using ArrayList...
public class Person : IComparable<Person>

But you fail to implement the non-generic interface IComparable.

If you use List<Person> instead of ArrayList (which is a good idea), the
problem disappears, but you should also implement the non-generic
counterpart to IComparable said:
public int CompareTo(Person other)
{
return this.Age - other.Age;
}

This implementation is not correct: you must check for the case that
"other" is null (and return a positive value in that case).
 
T

Tony Johansson

Hello!

Here is the new code implementing IComparable<T> and IComparable.
If I use List<T> it works fine.
If I instead use ArrayList I get runtime error with the message
"Failed to compare two elements in the array ?"
when the List.Sort() is called.

I just want to find the problem tom this runtime error ?

using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace ConsoleApplication15
{
class Program
{
static void Main(string[] args)
{
ArrayList list = new ArrayList();
list.Add(new Person("tony", 13));
list.Add(new Person("olle", 23));
list.Add(new Person("stina", 53));
list.Add(new Person("august", 3));
list.Add(new Person("roland", 33));
list.Sort();
foreach (Person pers in list)
Console.WriteLine(pers.Age);
}
}

public class Person : IComparable<Person>
{
string name;
int age;

public Person(string lname, int lage)
{
name = lname;
age = lage;
}

public int Age
{
set {age = value;}
get {return age; }
}

public int CompareTo(Person other)
{
if (other ==null)
return 1;
return this.Age - other.Age;
}

public int CompareTo(object obj)
{
if (obj is Person)
{
Person pers = obj as Person;
return this.Age - pers.Age;
}
else
{
if (obj == null)
return 1;
throw new ArgumentException("Object to compare to is not a
Person object");
}
}
}
}
 
J

Jeroen Mostert

Tony said:
Here is the new code implementing IComparable<T> and IComparable.

It's not actually doing that.
public class Person : IComparable<Person>

This should be

public class Person : IComparable<Person>, IComparable

You must explicitly mention an interface to implement it.

Also, because the non-generic method is strictly less useful than its
generic (strongly typed) counterpart, you should implement it explicitly to
prevent it from being called directly:

int IComparable.CompareTo(object obj) {
if (obj == null) return 1;
if (obj.GetType() != typeof(Person)) throw new ArgumentException();
return this.CompareTo((Person) obj);
}
 

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