I need help sorting a collection object. My Collection class provides functionality around an ArrayList which holds a list of Customer objects. I have added a Sort Method to the class. I am implementing IComparable in my Customer class and have written a CompareTo method. My Sort function fails and throws the error: System.ArgumentException: At least one object must implement IComparable.
My objective is to sort the customers by Lastname, Firstname, CustomerNo.
I've written up a little console app to reproduce this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp4Testing
{
class Program
{
static void Main(string[] args)
{
Customers customers = new Customers();
Customer customer = new Customer("C00066", "John", "Smith", "1234 Main St", "", "Boise", "ID", "53432", "US");
customers.Add(customer);
customer = new Customer("C00017", "Bob", "Jones", "1001 First Ave", "", "Detroit", "MI", "84772", "US");
customers.Add(customer);
customer = new Customer("C00024", "Susan", "Day", "PO Box 2509", "", "Dallas", "TX", "57212", "US");
customers.Add(customer);
customer = new Customer("C00009", "Bill", "Mason", "987 Washington Av", "", "Los Angeles", "CA", "90254", "US");
customers.Add(customer);
customer = new Customer("C00042", "Alice", "Jones", "1401 G St", "", "Atlanta", "GA", "65354", "US");
customers.Add(customer);
customer = new Customer("C00035", "Joan", "King", "879 Chestnut St", "", "Philadelphia", "PA", "22531", "US");
customers.Add(customer);
customer = new Customer("C00013", "John", "Smith", "67 Filmore Ave", "", "Chicago", "IL", "61535", "US");
customers.Add(customer);
Console.WriteLine("Customers in order as added:");
foreach (Customer cust in customers)
{
Console.WriteLine(cust.AccountNo + ", " + cust.FirstName + " " + cust.LastName);
}
Console.WriteLine();
customers.Sort();
Console.WriteLine("Customers sorted by Lastname, FirstName, AccountNo:");
foreach (Customer cust in customers)
{
Console.WriteLine(cust.AccountNo + ", " + cust.FirstName + " " + cust.LastName);
}
Console.ReadLine();
}
}
}
...and then my Customers and Customer classes:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace ConsoleApp4Testing
{
public class Customers : IEnumerable
{
private ArrayList m_customerList;
public Customers()
{
m_customerList = new ArrayList();
}
public Customer this[int index]
{
get { return (Customer)m_customerList[index]; }
set
{
if (index > (m_customerList.Count - 1))
{ m_customerList.Add(value); }
else
{ m_customerList[index] = value; }
}
}
public Customer this[Guid custId]
{
get { return (Customer)m_customerList[indexof(custId)]; }
}
public int indexof(Guid custId)
{
int i = 0;
foreach (Customer cst in this.m_customerList)
{
if (cst.ID == custId) { break; }
i++;
}
if (i >= this.count)
{ return -1; }
else
{ return i; }
}
public bool Exists(Guid custId)
{
int i = 0;
foreach (Customer cst in this.m_customerList)
{
if (cst.ID == custId) { break; }
i++;
}
if (i >= this.count)
{ return false; }
else
{ return true; }
}
public void Add(Customer customer)
{
//if (this.indexof(customer.ID) < 0) //Don't add the customer if it already exists
//{
this.m_customerList.Add(customer);
//}
}
public void Sort()
{
try {
this.m_customerList.Sort();
}
catch (Exception ex)
{ System.Diagnostics.Debug.Print(ex.ToString()); }
}
public int count
{
get { return m_customerList.Count; }
}
// IEnumerable Interface Implementation:
// Declaration of the GetEnumerator() method
// required by IEnumerable
public IEnumerator GetEnumerator()
{
return new customerEnumerator(this);
}
// Inner class implements IEnumerator interface:
private class customerEnumerator : IEnumerator
{
private int position = -1;
private Customers cstmrs;
public customerEnumerator(Customers cstmrs)
{
this.cstmrs = cstmrs;
}
// Declare the MoveNext method required by IEnumerator:
public bool MoveNext()
{
if (position < cstmrs.m_customerList.Count - 1)
{
position++;
return true;
}
else
{
return false;
}
}
// Declare the Reset method required by IEnumerator:
public void Reset()
{
position = -1;
}
// Declare the Current property required by IEnumerator:
public object Current
{
get
{
return cstmrs.m_customerList[position];
}
}
}
}
public class Customer : IComparable<Customer>
{
private Guid _id;
private string _acctNo;
private string _frstNm;
private string _lastNm;
private string _addr1;
private string _addr2;
private string _city;
private string _st;
private string _postal;
private string _country;
public Customer(Guid id)
{
this._id = id;
}
public Customer(string acctNo, string frstNm, string lastNm, string addr1, string addr2, string city, string state, string postal, string country)
{
this._acctNo = acctNo;
this._frstNm = frstNm;
this._lastNm = lastNm;
this._addr1 = addr1;
this._addr2 = addr2;
this._city = city;
this._st = state;
this._postal = postal;
this._country = country;
}
public int CompareTo(Customer c)
{
int compare;
compare = String.Compare(this.LastName, c.LastName, true);
if (compare == 0)
{
compare = this.FirstName.CompareTo(c.FirstName);
if (compare == 0)
{
compare = this.AccountNo.CompareTo(c.AccountNo);
}
}
return compare;
}
public Guid ID
{
get { return _id; }
set { this._id = value; }
}
public string AccountNo
{
get { return _acctNo; }
set { this._acctNo = value; }
}
public string FirstName
{
get { return _frstNm; }
set { this._frstNm = value; }
}
public string LastName
{
get { return _lastNm; }
set { this._lastNm = value; }
}
public string Address1
{
get { return _addr1; }
set { this._addr1 = value; }
}
public string Address2
{
get { return _addr2; }
set { this._addr2 = value; }
}
public string City
{
get { return _city; }
set { this._city = value; }
}
public string State
{
get { return _st; }
set { this._st = value; }
}
public string Postal
{
get { return _postal; }
set { this._postal = value; }
}
public string Country
{
get { return _country; }
set { this._country = value; }
}
}
}