Xây dựng một lớp Collection tự tạo.

70934431775758643202

Bài viết này sẽ hướng dẫn cách tạo những lớp custom collection bằng cách cho kế thừa từ System.Collections.CollectionBase. Trong khi .NET Framework có nhiều lớp collection mang tính chung chung, thì cũng không phải là type-safe (kiểu dữ liệu an toàn) vì chúng được thiết kế để chứa bất cứ đối tượng thuộc bất cứ kiểu dữ liệu nào. Nếu bạn muốn một collection chỉ chứa toàn những đối tượng thuộc một kiểu dữ liệu cụ thể đặc trưng nào đó, thì buộc lòng bạn phải tạo ra một lớp custom collection.

1. Các khái niệm

–   Bước đầu tiên trong việc thiết kế một custom collection là nhận diện ra lớp collection nào trên .NET là thích ứng  nhất mà ta sẽ dùng để làm lớp cơ bản trừu tượng cho custom collection của mình. Một kiểu dữ liệu collection bao giờ cũng duy trì ít nhất một danh sách nội tại mà theo đấy ta có thể trữ các item lần lượt được thêm vào. Các collection được phân biệt khác nhau dựa trên các hàm xử lý mà collection trưng ra lo việc tìm và đọc (retrieve), thêm và gỡ bỏ các item từ danh sách.

–    Một khi đã nhận diện xong lớp collection framework dùng để làm cơ sở, bạn có thể bắt đầu tạo lớp custom colleciton.  Trước tiên, ta định nghĩa một lớp mới kế thừa ưừ lớp collection framework. Tiếp theo, là cho đang năng hóa  (override) các hàm thành viên của lớp cơ sở có một số hoặc trị trả về của đối tượng kiểu dữ liệu. Bạn bảo đảm là thông số và trị trả về bạn override sẽ sử dụng kiểu dữ liệu custom của bạn. Thí dụ, nếu bạn muốn tạo một collection chứa các đối tượng Widget và lớp cơ sở chứa một hàm xử lý  Insert (item as Object) thì bạn phải override bở một hàm thay thế Insert (item as Widget). Việc này đảm bảo Widget có thể được chèn vào collection. Thường xuyên, hàm phủ quyết đơn giản có thể triệu gọi hàm xử lý tương ứng trên lớp cơ sở.

System.Collections.CollectionBase

Nếu bạn muốn tạo riêng cho mình một lớp colleciton hoàn toàn từ số 0, bạn có thể bắt đầu từ lớp CollectionBase. Đây là một lớp cơ bản trừu tượng chứa một protected ArrayList dùng để lưu trữ những thành viên mang tên InnerList, một thuộc tính Count và một hàm xử lý RemoveAt(). Ngoài ra, lớp này không có hàm xử lý nào khác, do đó bạn toàn quyền thi công những chức năng nào bạn thấy cần thiết. Tối thiểu, bạn phải thi công các hàm xử lý cho việc thêm, xóa và tìm kiếm từ collection.

2. Ứng dụng minh họa việc xây dựng một collction tự tạo.

–   Để hiểu rõ về cách tạo một collection theo ý của bạn. Chúng ta sẽ đi vào một ứng dụng mẫu minh họa cách tạo một type-safe custom collection mang tên Customers dùng để trữ những thể hiện của lớp Customer.

–  Các lớp sẽ xây dựng:

image

a. Tạo lớp Customer và lớp collection Customers

–   Muốn tạo một lớp custom collection, trước tiên bạn phải tạo một lớp cơ bản, Customer (khách hàng) chẳng hạn. Bạn để ý Customer không có chữ ‘s’. Dưới đây là lớp Customer.cs.

using System;
using System.Text;

namespace Customers
{
    class Customer {
        private string custAccount;   // Ma so tai khoang 11 ky so private string custFirstName;
        private string custLastName;

        public string DisplayData
        {
            get {
                return this.custAccount + ": " + this.custFirstName + " " + this.custLastName;
            }
        }

        public string AccountNumber
        {
            get { return custAccount; }
            set { custAccount = value; }
        }

        public string FirstName
        {
            get { return custFirstName; }
            set { custFirstName = value; }
        }

        public string LastName
        {
            get { return custLastName; }
            set { custLastName = value; }
        }
    }
}

–   Ta thấy lớp Customer này không có hàm khởi tạo, có một hàm DisplayData() để hiển thị một mẫu tin khách hàng và một số hàm set/get accessor định nghĩa 3 thuộc tính AccoutNumber, FirstName, LastName.

–   Sau khi tạo xong lớp Customer định nghĩa đối tượng khách hàng, bạn có thể tạo một lớp collection mang tên Customers. Lớp Customers này thuộc kiểu dữ liệu CollectionBase. Do đó phải khai báo kế thừa từ System.Collection.CollectionBase.

–  Lớp CollectionBase có một thuộc tính InnerList, thuộc kiểu dữ liệu ArrayList, cho phép bạn đi lấy một bản dãy ArrayList chứa tất cả các phần tử trong một thể hiện CollectionBase. Như vậy, khi kế thừa lớp CollectionBáe, bạn có thể truy cập một đối tượng bẩm sinh mang tên InnerList tượng trưng cho collection của bạn. Và bạn cso thể dùng các hàm Add(), Remove(), .. để thêm một đối tượng Customer vào collection Customer. Ngoài ra, bạn cũng có thể dùng hàm Item() để truy cập đối tượng Customer trong collection Customers. Khi truy cập một đối tượng, bạn cso thể trao qua index hoặc một biến đối tượng. Khi bạn trao một biến đối tượng thì có thể dùng hàm IndexOf() để tìm ra index của đối tượng Customer.

–   File Customers.cs có nội dung như sau:

using System;
using System.Text;

namespace Customers
{
    class Customers: System.Collections.CollectionBase {
        public Customer Add(Customer value)
        {
            this.InnerList.Add(value);
            return value;
        }

        public Customer Add(string FirstName, string LastName, string AccountNumber)
        {
            Customer cust = new Customer();
            cust.FirstName = FirstName;
            cust.LastName = LastName;
            cust.AccountNumber = AccountNumber;
            this.InnerList.Add(cust);
            return cust;
        }

        public Customer Item (int Index)
        {
            return (Customer)this.InnerList[Index];
        }

        public Customer Item(Customer cust)
        {
            int myIndex;
            myIndex = this.InnerList.IndexOf(cust);
            return (Customer)this.InnerList[myIndex];
        }

        public void Remove(Customer cust)
        {
            this.InnerList.Remove(cust);
        }

        public void Remove(int Index)
        {
            Customer cust;
            cust = (Customer)this.Item(Index);
            if (cust != null)
            {
                this.InnerList.Remove(cust);
            }
        }
    }
}

b. Viết code xử lý sử dụng collection Customers trên Form

–  Giao diện thiết kế của Chương trình như sau:

image

–   Giao diện chương trình được thiết kế đơn giản bao gồm: 4 button (btnAdd, btnShowItem, btnRemove, btnReload), 3 label, 3 textbox (txtFirstName, txtLastName, txtAccountNumber) và cuối cùng là một ô ListBox (lbxItem) dùng để hiển thị các mẫu tin Customer.

–  Nội dung File Form1.cs

using System;
using System.Text;
using System.Windows.Forms;

namespace Customers
{
    public partial class Form1 : Form {
        public Form1()
        {
            InitializeComponent();
        }

        private Customers myCustomers = new Customers();

        private void toolStripStatusLabel1_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process.Start(toolStripStatusLabel1.Text);
        }

        private void btnAdd_Click(object sender, EventArgs e)
        {
            Customer cust;
            int listNumber;
            cust = myCustomers.Add(txtFirstName.Text, txtLastName.Text, txtAccountNumber.Text);
            listNumber = lbxItem.Items.Add(cust);
            lbxItem.Refresh();
            txtAccountNumber.Text = string.Empty;
            txtFirstName.Text = string.Empty;
            txtLastName.Text = string.Empty;

        }

        private void btnShowItem_Click(object sender, EventArgs e)
        {
            Customer listCustomer;
            Customer cust;
            if (lbxItem.SelectedIndex > -1)
            {
                listCustomer = (Customer)lbxItem.SelectedItem;
                try {
                    cust = myCustomers.Item(listCustomer);
                    MessageBox.Show(cust.AccountNumber + " " + cust.FirstName + " " + cust.LastName, this.Text,
                        MessageBoxButtons.OK, MessageBoxIcon.Information);

                }
                catch (Exception ex)
                {

                    MessageBox.Show(ex.Message, ex.Source, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void btnRemove_Click(object sender, EventArgs e)
        {
            Customer listCustomer;
            Customer cust;
            if (lbxItem.SelectedIndex > -1)
            {
                listCustomer = (Customer)lbxItem.SelectedItem;
                try {
                    cust = myCustomers.Item(listCustomer);
                    myCustomers.Remove(cust);
                    lbxItem.Items.Remove(listCustomer);
                }
                catch (Exception ex)
                {

                    MessageBox.Show(ex.Message, ex.Source, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void btnReload_Click(object sender, EventArgs e)
        {
            lbxItem.Items.Clear();
            foreach (Customer cust in myCustomers)
            {
                lbxItem.Items.Add(cust);
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            int listNumber;
            lbxItem.DisplayMember = "DisplayData";
            Customer cust;
            cust = myCustomers.Add("Nguyễn Văn ", "A", "1234567890");
            listNumber = lbxItem.Items.Add(cust);
            cust = myCustomers.Add("Hồ Quý ", "B", "0987654321");
            listNumber = lbxItem.Items.Add(cust);
            cust = myCustomers.Add("Trần Quang ", "Diệu", "8907654321");
            listNumber = lbxItem.Items.Add(cust);
        }
    }
}

3. Kết luận và source code demo

–   Như bạn có thể thấy việc tạo một type safe custom collection chẳng qua là việc gới gọn (wrap) các hàm hành sự của thành viên InnerList của lớp cơ bản CollectionBase. Với các hàm thàn viên custom riêng của mình. Tuy nhiên nhiều custome collection mạnh hơn có thể được tạo ra rằng cách kế thừa từ những lớp System.Collections khác và cho ghi đè các hàm thành viên của các lớp này. Bạn có thể tập trung vào việc chọn lựa lớp cơ bản bằng cách khảo sát xem những tính năng chủ chốt mà lớp custom collection của bạn cần đến. Những hành xử thông dụng phổ biến cần phải xét đến bao gồm khả năng gắn liền một key với mỗi trị, chọn liệu xem các item sẽ được trữ trong những thứ tự sắp xếp hoặc theo thứ tự đưa vào và cho biết kích thước của danh sách mà lớp có thể được tối ưu hóa.

–  Click vào đây để download source code demo chương trình viết bằng C# trên Visual Studio 2010.

(Tham khảo Sổ Tay Kỹ Thuật Visual C# – tập 8)

Advertisements

About thanhcuong1990

Handsome and talent!! ^^
This entry was posted in C# and tagged . Bookmark the permalink.

2 Responses to Xây dựng một lớp Collection tự tạo.

  1. Jun says:

    Hay lắm bạn! mình đang rất cần tìm hiểu ! Cảm ơn

  2. Jun says:

    File demo lỗi rồi ! dù không cần thiết lắm nhưng mình muốn sờ tận tay một tí
    Nếu còn bạn up lại nhé

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s