Tải bản đầy đủ (.pdf) (9 trang)

Giao diện tập hợp

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (96.82 KB, 9 trang )

Giao diện tập hợp

Giao diện tập hợp
Bởi:
Khuyet Danh
Môi trường .NET cung cấp những giao diện chuẩn cho việc liệt kê, so sánh, và tạo các
tập hợp. Một số các giao diện trong số đó được liệt kê trong bảng 9.2 sau:
Giao diện cho tập hợp
Giao diện

Mục đích

IEnumerable

Liệt kê thông qua một tập hợp bằng cách sử dụngforeach.

ICollection

Thực thi bởi tất cả các tập hợp để cung cấp phương thức
CopyTo() cũng như các thuộc tính Count,ISReadOnly,
ISSynchronized, và SyncRoot.

IComparer

So sánh giữa hai đối tượng lưu giữ trong tập hợp đểsắp xếp
các đối tượng trong tập hợp.

IList

Sử dụng bởi những tập hợp mảng được chỉ mục


IDictionary

Dùng trong các tập hợp dựa trên khóa và giá trị
nhưHashtable và SortedList.

IDictionaryEnumerator

Cho phép liệt kê dùng câu lệnh foreach qua tập hợphỗ trợ
IDictionary.

Giao diện Ienumerable
Chúng ta có thể hỗ trợ cú pháp foreach trong lớp ListBoxTest bằng việc thực thi giao
diện IEnumerator. Giao diện này chỉ có một phương thức duy nhất là GetEnumerator(),
công việc của phương thức là trả về một sự thực thi đặc biệt của IEnumerator. Do vậy,
ngữ nghĩa của lớp Enumerable là nó có thể cung cấp một Enumerator:
public IEnumerator GetEnumerator() { return (IEnumerator)
new ListBoxEnumerator(this); }
Enumerator phải thực thi những phương thức và thuộc tính IEnumerator. Chúng có thể
được thực thi trực tiếp trong lớp chứa (trong trường hợp này là lớp ListBoxTest) hay bởi

1/9


Giao diện tập hợp

một lớp phân biệt khác. Cách tiếp cận thứ hai thường được sử dụng nhiều hơn, do chúng
được đóng gói trong lớp Enumerator hơn là việc phân vào trong các lớp chứa.
Do lớp Enumerator được xác định cho lớp chứa, vì theo như trên thì lớp
ListBoxEnumerator phải biết nhiều về lớp ListBoxTest. Nên chúng ta phải tạo cho
nó một sự thực thi riêng chứa bên trong lớp ListBoxTest. Lưu ý rằng phương thức

GetEnumerator truyền đối tượng List- BoxTest hiện thời (this) cho enumerator. Điều
này cho phép enumerator có thể liệt kê được các thành phần trong tập hợp của đối
tượng ListBoxTest. Ở đây lớp thực thi Enumerator là ListBoxEnumerator, đây là một
lớp private được định nghĩa bên trong lớp ListBoxTest. Lớp này thực thi đơn giản bao
gồm một thuộc tính public, và hai phương thức public là MoveNext(), và Reset(). Đối
tượng ListBoxTest được truyền vào như một đối mục của bộ khởi tạo. Ở đây nó được
gán cho biến thành viên myLBT. Trong hàm khởi tạo này cũng thực hiện thiết lập giá
trị biến thành viên index là -1, chỉ ra rằng chưa bắt đầu thực hiện việc enumerator đối
tượng:
public ListBoxEnumerator(ListBoxTest lbt) { this.lbt =
lbt; index = -1; }
Phương thức MoveNext() gia tăng index và sau đó kiểm tra để đảm bảo rằng việc thực
hiện không vượt quá số phần tử trong tập hợp của đối tượng:
public bool MoveNext() { index++; if (index >=
lbt.strings.Length) return false; else return true; }
Phương thức IEnumerator.Reset() không làm gì cả nhưng thiết lập lại giá trị của index là
-1. Thuộc tính Current trả về đối tượng chuỗi hiện hành. Đó là tất cả những việc cần làm
cho lớp ListBoxTest thực thi một giao diện IEnumerator. Câu lệnh foreach sẽ được gọi
để đem về một enumerator, và sử dụng nó để liệt kê lần lượt qua các thành phần trong
mảng. Sau đây là toàn bộ chương trình minh họa cho việc thực thi trên.
Tạo lớp ListBox hỗ trợ enumerator.
----------------------------------------------------------------------------namespace Programming_CSharp
{
using System;
using System.Collections;

2/9


Giao diện tập hợp


// tạo một control đơn giản
public class ListBoxTest: IEnumerable
{
// lớp thực thi riêng ListBoxEnumerator
private class ListBoxEnumerator : IEnumerator
{
public ListBoxEnumerator(ListBoxTest lbt)
{
this.lbt = lbt;
index = -1;
}
// gia tăng index và đảm bảo giá trị này hợp lệ
public bool MoveNext()
{
index++;
if (index >= lbt.strings.Length)
return false;
else
return true;
}
public void Reset()
{
3/9


Giao diện tập hợp

index = -1;
}

public object Current
{
get
{
return( lbt[index]);
}
}
private ListBoxTest lbt;
private int index;
}
// trả về Enumerator
public IEnumerator GetEnumerator()
{
return (IEnumerator) new ListBoxEnumerator(this);
}
// khởi tạo listbox với chuỗi
public ListBoxTest (params string[] initStr)
{
strings = new String[10];
// copy từ mảng chuỗi tham số
4/9


Giao diện tập hợp

foreach (string s in initStr)
{
strings[ctr++] = s;
}
}

public void Add(string theString)
{
strings[ctr] = theString;
ctr++;
}
// cho phép truy cập giống như mảng
public string this[int index]
{
get
{
if ( index < 0 || index >= strings.Length)
{
// xử lý index sai
}
return strings[index];
}
set
5/9


Giao diện tập hợp

{
strings[index] = value;
}
}
// số chuỗi nắm giữ
public int GetNumEntries()
{
return ctr;

}
private string[] strings;
private int ctr = 0;
}
public class Tester
{
static void Main()
{
ListBoxTest lbt = new ListBoxTest("Hello", "World");
lbt.Add("What");
lbt.Add("Is");
lbt.Add("The");
lbt.Add("C");
lbt.Add("Sharp");
6/9


Giao diện tập hợp

string subst = "Universe";
lbt[1] = subst;
// truy cập tất cả các chuỗi int count =1;
foreach (string s in lbt)
{
Console.WriteLine("Value {0}: {1}",count, s);
count++;
}
}
}
}

----------------------------------------------------------------------------Kết quả:
Value 1: Hello
Value 2: Universe
Value 3: What
Value 4: Is
Value 5: The
Value 6: C
Value 7: Sharp
Value 8:
Value 9:

7/9


Giao diện tập hợp

Value 10:
----------------------------------------------------------------------------Chương trình thực hiện bằng cách tạo ra một đối tượng ListBoxTest mới và truyền hai
chuỗi vào cho bộ khởi dựng. Khi một đối tượng được tạo ra thì mảng của chuỗi được
định nghĩa có kích thước 10 chuỗi. Năm chuỗi sau được đưa vào bằng phương thức
Add(). Và chuỗi thứ hai sau đó được cập nhật lại giá trị mới. Sự thay đổi lớn nhất của
chương trình trong phiên bản này là câu lệnh foreach được gọi để truy cập từng chuỗi
trong ListBox. Vòng lặp foreach tự động sử dụng giao diện IEnumerator bằng cách gọi
phương thức GetEnumerator(). Một đối tượng ListBoxEnumerator được tạo ra và giá
trị index = -1 được thiết lập trong bộ khởi tạo. Vòng lặp foreach sau đó gọi phương
thức MoveNext(), khi đó index sẽ được gia tăng đến 0 và trả về true. Khi đó foreach sử
dụng thuộc tính Current để nhận lại chuỗi hiện hành. Thuộc tính Current gọi chỉ mục
của ListBox và nhận lại chuỗi được lưu trữ tại vị trí 0. Chuỗi này được gán cho biến s
được định nghĩa trong vòng lặp, và chuỗi này được hiển thị ra màn hình console. Vòng
lặp tiếp tục thực hiện tuần tự từngt bước: MoveNext(), Current(), hiển thị chuỗi cho đến

khi tất cả các chuỗi trong list box được hiển thị. Trong minh họa này chúng ta khai báo
mảng chuỗi có 10 phần tử, nên trong kết quả ta thấy chuỗi ở vị trí 8, 9, 10 không có nội
dung.

Giao diện ICollection
Một giao diện quan trọng khác cho những mảng và cho tất cả những tập hợp được cung
cấp bởi .NET Framework là ICollection. ICollection cung cấp bốn thuộc tính: Count,
IsReadOnly, IsSynchronized, và SyncRoot. Ngoài ra ICollection cũng cung cấp một
phương thức CopyTo(). Thuộc tính thường được sử dụng là Count, thuộc tính này trả về
số thành phần trong tập hợp:
for(int i = 0; i < myIntArray.Count; i++) { //... }
Ở đây chúng ta sử dụng thuộc tính Count của myIntArray để xác định số đối tượng có
thể được sử dụng trong mảng.

Giao diện IComparer
Giao diện IComparer cung cấp phương thức Compare(), để so sánh hai phần tử trong
một tập hợp có thứ tự. Phương thức Compare() thường được thực thi bằng cách gọi
phương thức CompareTo() của một trong những đối tượng. CompareTo() là phương
thức có trong tất cả đối tượng thực thi IComparable. Nếu chúng ta muốn tạo ra những
lớp có thể được sắp xếp bên trong một tập hợp thì chúng ta cần thiết phải thực thi
IComparable.

8/9


Giao diện tập hợp

.NET Framework cung cấp một lớp Comparer thực thi IComparable và cung cấp một số
thực thi cần thiết. Phần danh sách mảng sau sẽ đi vào chi tiết việc thực thi IComparable.


9/9



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×