618
Chương 16: Các giao diện và mẫu thông dụng
Nếu muốn sắp xếp kiểu của bạn chỉ theo một thứ tự nào đó (như ID tăng dần, hay tên theo thứ
tự alphabet), bạn nên hiện thực giao diện
IComparable
. Giao diện này định nghĩa phương thức
CompareTo
như sau:
int CompareTo(object obj);
Đối tượng (
obj
) được truyền cho phương thức phải cùng kiểu với đối tượng đang gọi, nếu
không
CompareTo
sẽ ném ngoại lệ
System.ArgumentException
. Giá trị do
CompareTo
trả về
được tính như sau:
•
Nếu đối tượng hiện tại nhỏ hơn
obj
, trả về một số âm (chẳng hạn, -1).
•
Nếu đối tượng hiện tại có cùng giá trị như
obj
, trả về zero.
•
Nếu đối tượng hiện tại lớn hơn
obj
, trả về một số dương (chẳng hạn, 1).
Phép so sánh này thực hiện điều gì là tùy thuộc vào kiểu đã hiện thực giao diện
IComparable
.
Ví dụ, nếu muốn sắp xếp dựa theo tên, bạn cần thực hiện phép so sánh chuỗi (
String
). Tuy
nhiên, nếu muốn sắp xếp dựa theo ngày sinh, bạn cần thực hiện phép so sánh ngày
(
System.DateTime
).
Để hỗ trợ nhiều dạng sắp xếp cho một kiểu cụ thể, bạn phải hiện thực riêng rẽ từng kiểu trợ
giúp và các kiểu này hiện thực giao diện
IComparer
. Giao diện này định nghĩa phương thức
Compare
như sau:
int Compare(object x, object y);
Kiểu trợ giúp phải đóng gói logic cần thiết để so sánh hai đối tượng và trả về một giá trị dựa
trên logic như sau:
•
Nếu
x
nhỏ hơn
y
, trả về một số âm (chẳng hạn, -1).
•
Nếu
x
có cùng giá trị như
y
, trả về zero.
•
Nếu
x
lớn hơn
y
, trả về một số dương (chẳng hạn, 1).
Lớp
Newspaper
dưới đây hiện thực cả giao diện
IComparable
và
IComparer
. Phương thức
Newspaper.CompareTo
thực hiện phép so sánh không phân biệt chữ hoa-thường hai đối tượng
Newspaper
dựa trên trường
name
của chúng. Một lớp
private
lồng bên trong có tên là
AscendingCirculationComparer
hiện thực
IComparer
và so sánh hai đối tượng
Newspaper
dựa
trên trường
circulation
của chúng. Đối tượng
AscendingCirculationComparer
được thu lấy
bằng thuộc tính tĩnh
Newspaper.CirculationSorter
.
using System;
using System.Collections;
public class Newspaper : IComparable {
private string name;
private int circulation;