Ä Hiện
thực kiểu khả-định-dạng (formattable type)
Í Bạn cần hiện thực một kiểu có thể được sử dụng theo các format string, và có
thể tạo ra những biểu diễn chuỗi khác nhau cho nội dung của nó dựa vào
format specifier.
▪ Hiện thực giao diện System.IFormattable.
Đoạn mã dưới đây minh họa cách sử dụng format specifier (phần in đậm) trong phương
thức WriteLine của lớp System.Console.
double a = 345678.5678;
uint b = 12000;
byte c = 254;
Console.WriteLine("a =
{0}
, b =
{1}
, and c =
{2}
", a, b, c);
Console.WriteLine("a =
{0:c0}
, b =
{1:n4}
, and c =
{2,10:x5}
", a, b, c);
Khi chạy trên máy với thiết lập bản địa là English (U.K.), đoạn mã này sẽ cho kết xuất
như sau (thay đổi nội dung của format specifier sẽ thay đổi định dạng của kết xuất một
cách đáng kể mặc dù dữ liệu vẫn không thay đổi):
a = 345678.5678, b = 12000, and c = 254
a = £345,679, b = 12,000.0000, and c = 000fe
Để kích hoạt việc hỗ trợ format specifier, bạn phải hiện thực giao diện IFormattable. Giao
private string[] names;
// Phương thức khởi dựng dùng để thiết lập danh hiệu và tên.
public Person(string title, params string[] names) {
this.title = title;
this.names = names;
}
// Chép đè phương thức Object.ToString để trả về
// tên theo định dạng general.
public override string ToString() {
return ToString("G", null);
}
// Hiện thực phương thức IFormattable.ToString để trả về
// tên theo các dạng khác nhau dựa trên format string.
public string ToString(string format,
IFormatProvider formatProvider) {
string result = null;
// Sử dụng định dạng general nếu format = null.
if (format == null) format = "G";
// Nội dung của format string cho biết định dạng của tên.
switch (format.ToUpper()[0]) {
case 'S':
// Sử d
}
}
Đoạn mã dưới đây trình bày cách sử dụng khả năng định dạng của lớp Person:
// Tạo một đối tượng Person mô tả một người có tên là
// Mr. Richard Glen David Peters.
Person person =
new Person("Mr", "Richard", "Glen", "David", "Peters");
// Hiển thị tên bằng nhiều format string khác nhau.
System.Console.WriteLine("Dear {0:G},", person);
System.Console.WriteLine("Dear {0:P},", person);
System.Console.WriteLine("Dear {0:I},", person);
System.Console.WriteLine("Dear {0},", person);
System.Console.WriteLine("Dear {0:S},", person);
Khi được thực thi, đoạn mã này sinh ra kết xuất như sau:
Dear Richard Peters,
Dear Mr. R. G. D. Peters,
Dear Richard,
Dear Richard Peters,
Dear R. Peters,
Ä Hiện
thực lớp ngoại lệ tùy biến
Í Bạn cần tạo một lớp ngoại lệ tùy biến sao cho bạn có thể sử dụng cơ chế thụ lý
ngoại lệ của bộ thực thi để thụ lý các ngoại lệ đặc-trưng-ứng-dụng.
▪ Tạo một lớp khả-tuần-tự-hóa, thừa kế lớp System.ApplicationException và
hiện thực các phương thức khởi dựng với chữ ký như sau:
public CustomException() : base() {}
public CustomException(string message) : base(message) {}
public CustomException(string message, Exception inner)
: base(message, inner) {}
8. Hiện thực ba phương thức khởi dựng public với chữ ký như dưới đây và bảo đảm
chúng gọi phương thức khởi dựng của lớp cơ sở:
public CustomException() : base() {}
public CustomException(string message): base(message) {}
public CustomException(string message, Exception inner)
: base(message, inner) {}
9. Làm cho lớp ngoại tùy biến trở nên khả-tuần-tự-hóa để bộ thực thi có thể marshal
các thể hiện của nó qua các biên miền ứng dụng và biên máy. Áp dụng đặc tính
System.SerializableAttribute thường là đã đủ cho các lớp ngoại lệ không hiện thực
các thành viên dữ liệu tùy biến. Tuy nhiên, vì Exception hiện thực giao diện
System.Runtime.Serialization.ISerializable nên nếu ngoại lệ của bạn có khai báo các
thành viên dữ liệu tùy biến, bạn phải chép đè phương thức
ISerializable.GetObjectData của l
ớp Exception cũng như hiện thực một phương thức
khởi dựng giải tuần tự hóa với chữ ký như dưới đây. Nếu lớp ngoại lệ của bạn là
sealed, đánh dấu phương thức khởi dựng giải tuần tự hóa là private; nếu không thì
đánh dấu nó là protected.
private CustomException(SerializationInfo info,
StreamingContext context) {}
Phương thức GetObjectData và phương thức khởi dựng giải tuần tự hóa phải gọi
phương thức tương đương trong lớp cơ sở để cho phép lớp cơ sở thực hiện tuần tự
hóa và giải tuần tự hóa dữ liệu của nó một cách đúng đắn (xem mục 16.1 để biết
cách làm cho một lớp trở nên khả-tuần-tự-hóa).
Dưới đây là một lớp ngo
ại lệ tùy biến có tên là CustomException (thừa kế lớp
ApplicationException). Lớp này khai báo hai thành viên dữ liệu tùy biến: một chuỗi có
tên là stringInfo và một giá trị luận lý có tên là booleanInfo.
using System;
using System.Runtime.Serialization;
}
// Các phương thức khởi dựng cho phép mã lệnh thiết lập
// các thành viên dữ liệu tùy biến.
public CustomException(string message, string stringInfo,
bool booleanInfo): this(message) {
this.stringInfo = stringInfo;
this.booleanInfo = booleanInfo;
}
public CustomException(string message, Exception inner,
string stringInfo, bool booleanInfo) : this(message, inner) {
this.stringInfo = stringInfo;
this.booleanInfo = booleanInfo;
}
// Các thuộc tính chỉ-đọc cho phép truy xuất đến các
// thành viên dữ liệu tùy biến.
public string StringInfo {
get { return stringInfo; }
}
public bool BooleanInfo {
get { return booleanInfo; }
}
// Phương thức GetObjectData (được khai báo trong giao diện
// ISerializable) được sử dụng trong quá trình tuần tự hóa
// CustomException. Vì CustomException có khai báo các thành
// viên dữ liệu tùy biến nên nó phải chép đè hiện thực
i các lớp ngoại lệ.
Ngoài ra, tránh phân cấp lớp theo chiều sâu mà nên phân cấp cạn, theo chiều rộng.