排序C#集合

时间:2015-03-06 14:03:56

标签: c# sorting arraylist collections

我需要帮助排序集合对象。 My Collection类提供了一个ArrayList的功能,它包含一个Customer对象列表。我在课堂上添加了一个排序方法。我正在我的Customer类中实现IComparable并编写了一个CompareTo方法。我的Sort函数失败并抛出错误:System.ArgumentException:至少有一个对象必须实现IComparable。

我的目标是按姓氏,名字,客户名称对客户进行排序。

我已经写了一个小控制台应用程序来重现这个:

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();
        }
    }
}

...然后是我的客户和客户类:

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; }
        }
    }
}

3 个答案:

答案 0 :(得分:2)

只需使用标准通用列表和Linq进行排序

        List<Customer> customers = new List<Customer>();

        foreach(Customer cust in customers.OrderBy(c=>c.LastName).ThenBy(c=>c.FirstName).ThenBy(c=>c.CustomerNo))
        {
        }

答案 1 :(得分:1)

我怀疑非通用ArrayList正在寻找非通用IComparable,但您已经实现了通用IComparable<T>。尝试实现非泛型的:

public class Customer : IComparable
{
    // ...

    public int CompareTo(object obj) {
        if (obj == null) return 1;

        Customer c = obj as Customer;
        if (c == null) 
           throw new ArgumentException("Object is not a Customer");

        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;
    }
}

相反,您可以使用泛型集合而不是非泛型ArrayList。然后,在不实施IComparable<T>的情况下,甚至可以更简单地完成排序,因为您的Customers实现可以在内部使用通用集合上的.OrderBy()扩展。

答案 2 :(得分:0)

尝试将m_customerList声明更改为:

List<Customer> m_customerList;

您需要指定List要保留的对象才能正确调用Sort方法。您必须使用List而不是ArrayList来指定对象类型。