对C#集合进行排序

本文关键字:排序 集合 | 更新日期: 2024-10-24 01:25:22

我需要帮助对集合对象进行排序。My Collection类提供了关于ArrayList的功能,ArrayList包含Customer对象的列表。我已经向类中添加了一个排序方法。我正在Customer类中实现IComparable,并编写了一个CompareTo方法。My 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; }
        }
    }
}

对C#集合进行排序

只需使用标准泛型列表和Linq对进行排序

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

我怀疑非通用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()扩展。

尝试将m_customerList声明更改为:

List<Customer> m_customerList;

您需要指定List要容纳的对象,以便正确调用Sort方法。您必须使用List而不是ArrayList来指定对象类型。