1. Trang chủ
  2. » Công Nghệ Thông Tin

Tài liệu Các giao diện và mẫu phần 4 ppt

8 343 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Hiện thực kiểu khả-định-dạng (formattable type)
Chuyên ngành Computer Science
Thể loại Bài giảng PowerPoint
Định dạng
Số trang 8
Dung lượng 176,2 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Ä 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

Trang 1

Ä 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 diện này khai báo một phương thức có tên là ToString với chữ ký như sau:

string ToString(string format, IFormatProvider formatProvider);

Đối số format là một System.String chứa format string (chuỗi định dạng) Format string

là phần format specifier phía sau dấu hai chấm Ví dụ, trong format specifier {2,10:x5} (ở

ví dụ trên), "x5" là format string Format string chứa những chỉ thị mà thể hiện

IFormattable sẽ sử dụng khi tạo ra dạng chuỗi cho nội dung của nó Tài liệu NET Framework phát biểu rằng: những kiểu có hiện thực IFormattable thì phải hỗ trợ format string "G" (general), nhưng những format string được hỗ trợ khác thì phụ thuộc vào hiện

thực Đối số format là null nếu format specifier không chứa phần format string, ví dụ {0} hay {1,20}

Đối số formatProvider là tham chiếu đến một thể hiện System.IFormatProvider (dùng để

truy xuất các thông tin bản địa—bao gồm các dữ liệu như biểu tượng tiền tệ hay số lượng

chữ số thập phân) Theo mặc định, formatProvider là null, nghĩa là bạn sẽ sử dụng các thiết lập bản địa của tiểu trình hiện hành (có thể lấy được thông qua phương thức tĩnh CurrentCulture của lớp System.Globalization.CultureInfo)

.NET Framework chủ yếu sử dụng IFormattable để hỗ trợ việc định dạng các kiểu giá trị,

nhưng nó có thể được sử dụng cho bất kỳ kiểu nào Ví dụ, lớp Person dưới đây có hiện thực giao diện IFormattable Lớp này chứa danh hiệu và tên của một người, và sẽ trả về

Trang 2

tên theo các định dạng khác nhau tùy vào format string Lớp Person không sử dụng các thiết lập bản địa do đối số formatProvider cung cấp

using System;

public class Person : IFormattable {

// Các thành viên private dùng để lưu trữ danh hiệu

// và tên của một người

private string title;

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ụng dạng short: first-initial và surname

Trang 3

result = names[0][0] + " " + names[names.Length-1];

break;

case 'P':

// Sử dụng dạng polite: title, initials, và surname

if (title != null && title.Length != 0) {

result = title + " ";

}

for (int count = 0; count < names.Length; count++) {

if ( count != (names.Length - 1)) {

result += names[count][0] + " ";

} else {

result += names[count];

}

}

break;

case 'I':

// Sử dụng dạng informal: chỉ có first-name

result = names[0];

break;

case 'G':

default:

// Sử dụng dạng mặc định/general: first-name và surname

result = names[0] + " " + names[names.Length-1];

break;

}

return result;

}

}

Đ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);

Trang 4

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,

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) {}

Thêm bất cứ thành viên dữ liệu tùy biến nào mà ngoại lệ cần đến, bao gồm các phương thức khởi dựng và các thuộc tính cần thiết để thao tác các thành viên dữ liệu

Các lớp ngoại lệ là duy nhất, bạn không được khai báo các lớp mới để hiện thực chức năng mới hay mở rộng Cơ chế thụ lý ngoại lệ của bộ thực thi (được trưng ra bởi các lệnh: try, catch, và finally) làm việc dựa trên kiểu ngoại lệ bị ném, chứ không phải các thành viên chức năng hay dữ liệu được hiện thực bởi ngoại lệ bị ném

Nếu cần ném một ngoại lệ, bạn nên sử dụng một lớp ngoại lệ có sẵn trong thư viện lớp

.NET Framework (nếu tồn tại một lớp phù hợp) Dưới đây là một số ngoại lệ hữu ích:

1 System.ArgumentNullException—khi mã lệnh truyền một giá trị đối số null cho một phương thức không hỗ trợ đối số null

2 System.ArgumentOutOfRangeException—khi mã lệnh truyền cho phương thức một giá trị đối số không phù hợp (lớn quá hay nhỏ quá)

3 System.FormatException—khi mã lệnh truyền cho phương thức một đối số String chứa dữ liệu không được định dạng đúng

Nếu không có lớp ngoại lệ nào đáp ứng được nhu cầu của bạn, hoặc bạn cảm thấy ứng dụng của bạn sẽ được lợi từ việc sử dụng các ngoại lệ đặc-trưng-ứng-dụng, bạn có thể tạo

Trang 5

một lớp ngoại lệ cho mình Để tích hợp ngoại lệ tùy biến với cơ chế thụ lý ngoại lệ của bộ thực thi và vẫn giữ tính nhất quán với mẫu được hiện thực bởi các lớp ngoại lệ có sẵn, bạn cần:

4 Đặt một tên có ý nghĩa cho lớp ngoại lệ tùy biến, kết thúc bằng từ Exception, chẳng hạn, TypeMismatchException hay RecordNotFoundException

5 Thừa kế lớp ApplicationException Về cơ bản, lớp ngoại lệ tùy biến phải thừa kế lớp System.Exception, nếu không trình biên dịch sẽ dựng lên lỗi khi bạn ném ngoại

lệ ApplicationException thừa kế Exception và được đề nghị làm lớp sơ sở cho tất cả các lớp ngoại lệ đặc-trưng-ứng-dụng

6 Đánh dấu lớp ngoại lệ tùy biến là sealed nếu bạn không muốn các lớp ngoại lệ khác

có thể thừa kế nó

7 Hiện thực thêm các thuộc tính và các thành viên dữ liệu để hỗ trợ các thông tin tùy biến mà lớp ngoại lệ này cung cấp

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

Trang 6

using System;

using System.Runtime.Serialization;

// Đánh dấu CustomException là Serializable (khả-tuần-tự-hóa) [Serializable]

public sealed class CustomException : ApplicationException {

// Các thành viên dữ liệu tùy biến cho CustomException

private string stringInfo;

private bool booleanInfo;

// Ba phương thức khởi dựng chuẩn; chỉ cần gọi phương thức // khởi dựng của lớp cơ sở (System.ApplicationException)

public CustomException() : base() {}

public CustomException(string message): base(message) {}

public CustomException(string message, Exception inner)

: base(message, inner) {}

// Phương thức khởi dựng giải tuần tự hóa (cần cho giao diện // ISerialization) Vì CustomException là sealed nên phương thức // khởi dựng này là private Nếu CustomException không phải là // sealed thì phương thức khởi dựng này nên được khai báo là // protected để các lớp dẫn xuất có thể gọi nó trong quá trình // giải tuần tự hóa

private CustomException(SerializationInfo info,

StreamingContext context) : base (info, context) {

// Giải tuần tự hóa mỗi thành viên dữ liệu tùy biến

stringInfo = info.GetString("StringInfo");

booleanInfo = info.GetBoolean("BooleanInfo");

}

// 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;

Trang 7

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

// GetObjectData của lớp cơ sở

public override void GetObjectData(SerializationInfo info, StreamingContext context) {

// Tuần tự hóa các thành viên dữ liệu tùy biến

info.AddValue("StringInfo", stringInfo);

info.AddValue("BooleanInfo", booleanInfo);

// Gọi lớp cơ sở để tuần tự hóa các thành viên của nó

base.GetObjectData(info, context);

}

// Chép đè thuộc tính Message của lớp cơ sở (để kèm các

// thành viên dữ liệu tùy biến vào)

public override string Message {

get {

Trang 8

string message = base.Message;

if (stringInfo != null) {

message += Environment.NewLine +

stringInfo + " = " + booleanInfo;

}

return message;

}

}

}

Trong các ứng dụng lớn, bạn sẽ thường xuyên hiện thực một vài lớp ngoại lệ tùy biến Bạn cần lưu tâm đến cách tổ chức các ngoại lệ tùy biến và mã lệnh sẽ sử dụng chúng như thế nào Nói chung, tránh tạo ra các lớp ngoại lệ mới trừ khi mã lệnh cần nỗ lực bắt ngoại

lệ đó; sử dụng các thành viên dữ liệu để thu thông tin, chứ không phả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

Ngày đăng: 21/01/2014, 01:20

TỪ KHÓA LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w