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

C# và các lớp cơ sở Xử lý chuỗi – Phần 2 pptx

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 (125.61 KB, 14 trang )

C# và các lớp cơ sở
Xử lý chuỗi – Phần 2


Các thành viên của StringBuilder
Chúng ta đã minh hoạ 1 hàm dựng của StringBuilder, mà lấy thông số khởi
tạo là chuỗi và dung lượng.cũng có một vài cái khác , trong số chúng, ta có
thể cung cấp chỉ 1 chuỗi :
StringBuilder sb = new StringBuilder("Hello");
hoặc chỉ cung cấp dung luợng , chuỗi trống:
StringBuilder sb = new StringBuilder(20);
Ngoại trừ 2 thuộc tính trên ta còn có thuộc tính chỉ đọc MaxCapacity chỉ
định giới hạn mà 1 thể hiện của StringBuilder cho phép .mặc định , số này là
int.MaxValue ( khoảng 2 tỷ).
// dung lượng khởi tạo là 100 nhưng lớn nhất là 500
// do đó StringBuilder không thể phát triển hơn 500 kí tự được.
// chúng sẽ tung biệt lệ nếu ta cố làm điều đó.
StringBuilder sb = new StringBuilder("Hello", 100, 500);
StringBuilder sb = new StringBuilder(100, 500);
Ta có thể thiết lập dung lượng ở bất cứ đâu .nếu dung lượng thiêt lập nhỏ
hơn chuỗi hiện hành hoặc lớn hơn độ dài lớn nhất thì biệt lệ sẽ được tung ra.
StringBuilder sb = new StringBuilder("Hello");
sb.Capacity = 100;
Phương thức chính StringBuilder bao gồm :
Append() : thêm 1 chuỗi vào chuỗi đương thời
AppendFormat() :thêm 1 chuỗi mà được trình bày từ các chỉ định định dạng
Insert() :chèn 1 chuỗi con vào chuỗi đương thời
Remove() :bỏ các kí tự từ chuỗi đương thời
Replace() :thay thế kí tự này bằng kí tự khác hoặc chuỗi con này bằng chuỗi
con khác trong chuỗi đương thời
ToString() :trả về chuỗi đương thời ép thành 1 đối tượng System.Object (


nạp chồn từ System.Object)
Vào lúc viết , không thể ép kiểu ( tường minh hay không tưòng minh) từ
StringBuilder sang String. nếu ta muốn xuất nội dung của StringBuilder như
là 1 String , cách duy nhất để làm là dùng phương thức Tostring()
Định dạng Chuỗi
Nếu ta muốn những lớp mà ta viết thân thiện với người sử dụng , thì chúng
cần để trình bày chuỗi theo bất cứ cách nào mà người sử dụng muốn
dùng.Thời gian chạy .NET định nghĩa 1 cách chuẩn để làm : dùng 1
interface hoặc IFormatable.biểu diễn làm thế nào để thêm những đặc tính
quan trọng đến lớp của ta và những cấu trúc là chủ đề của phần này.
ta thường chỉ định định dạng của biến được trình bày khi gọi
Console.Writeline. do đó ta sẽ lấy phương thức này làm ví dụ, mặc dù hầu
hết những điều ta sắp học có thể ứng dụng trong bất cứ tình huống nào mà ta
muốn định dạng chuỗi
Ví dụ:
double d = 13.45;
int i = 45;
Console.WriteLine("The double is {0,10:E} and the int contains {1}", d, i);
Chuỗi định dạng tự nó bao gồm hầu hết văn bản được trình bày,nhưng bất
cứ ở đâu có biến được định dạng , chỉ mục của nó trong danh sách thông số
trong dấu ngoặc.có thể là thông tin khác bên trong dấu ngoặc về việc định
dạng của mục đó :
số kí tự được giữ bởi sự trình bày của mục có thể xuất hiện, thông tin này sẽ
có dấu phảy đứng trước.một số âm chỉ định rằng mục đó đưọc canh
trái,trong khi 1 số dương chỉ định mục đó được canh phải. nếu mục đó giữ
nhiều kí tự hơn được yêu cầu, nó vẫn xuất hiện đầy đủ.
Một chỉ định định dạng cũng có thể xuất hiện.điều này sẽ được đặt trước bởi
dấu hai chấm và chỉ định cách ta muốn mục được định dạng. ví dụ ta muốn
định dạng số như kiểu tiền tệ hoặc trình bày theo ký hiệu khoa học ?
Đặc tả Áp dụng đến Ý nghĩa Ví dụ

C numeric types
locale-specific
monetary value
$4834.50 (USA)£4834.50
(UK)
D
integer types
only
general integer 4834
E numeric types scientific notation 4.834E+003
F numeric types fixed point decimal

4384.50
G numeric types general number 4384.5
Đặc tả Áp dụng đến Ý nghĩa Ví dụ
N numeric types
usual locale
specific format for
numbers
4,384.50 (UK/USA)4
384,50 (continental Europe)

P numeric types
Percentage
notation
432,000.00%
X
integer types
only
hexadecimal

format
1120 (NB. If you want to
display 0x1120, you'd need
to write out the 0x
separately)

Làm thế nào chuỗi được định dạng
Xem ví dụ sau:
Console.WriteLine("The double is {0,10:E} and the int contains {1}", d, i);
Thực vậy, Console.Writeline() chỉ việc kiểm soát toàn bộ tập thông số bằng
cách chuyển đến phương thức static, String.Format()- cũng phương thức này
được gọi nếu ta muốn định dạng các giá trị trong chuỗi theo các mục đích
khác , như là trình bày trong textbox.Để làm rõ những gì mã nguồn thực sự
thực thi phương thức này là gì ,ta sẽ xem xét việc thi hành phương thức
oveload với 3 thông số của phương thức Writeline() như sau :
:
// giống như thực thi Console.Writeline()
public void WriteLine(string format, object arg0, object arg1)
{
Console.WriteLine(string.Format(format, arg0, arg1));
}
Overload 1 thông số của phương thức này, đơn giản viết nội dung của chuỗi
được trình bày,không làm bất cứ định dạng gì trên nó.
String.format() cần xây dựng chuỗi cuối bằng cách thay thế mỗi phần đặc tả
định dạng bằng việc trình bày chuỗi thích hợp của đối tượng tương ứng.tuy
nhiên như đã biết , chính xác trong tình huống này ta cần thể hiện
Stringbuilder hơn là thể hiện string. trong ví dụ ta đang xét , 1 thể hiện
StringBuilder sẽ được tạo ra và khởi tạo với phần đầu là chuỗi " The double
is" . phương thức StringBuilder.AppendFormat() sẽ được gọi, truyền phần
đặc tả định dạng dầu tiên , {0,10:E} ,và đối tượng kết hợp kiểu double này

sẽ được thêm vào chuỗi đang được xây dựng, quy trình này sẽ tiếp tục với
việc gọi nhiều lần StringBuilder.Append() và StringBuilder.AppendFormat()
cho đến khi toàn bộ chuỗi được định dạng đã xong.
Bởi vì StringBuilder.AppendFormat() sẽ cần minh họa cách định dạng thực
sự đối tượng. điều đầu tiên sẽ là thăm dò đối tượng để xem liệu nó có thực
thi 1 interface IFormatable ( trong namespace System ) hay chưa.ta có thể
thử ép kiểu 1 đối tượng thành 1 interface và xem coi ép kiểu được không.
nếu kiểm tra thất bại , thì AppendFormat() đơn giản gọi phương thức
tostring() của đối tượng,( do phương thức này được tất cả các đối tượng
cùng thừa kế từ System.Object hoặc do nạp chồng).
IFormattable định nghĩa giống như một phương thức, mà cũng được goị
ToString().tuy nhiên phương thức này lấy 2 thông số, đối lập với phiên bản
System.Object , mà không lấy bất kì thông số nào. đây là định nghĩa cho
IFormattable:
interface IFormattable
{
string ToString(string format, IFormatProvider formatProvider);
}
Thông số đầu tiên mà hàm overload của Tostring() này lấy là chuỗi mà đặc
tả định dạng được yêu cầu.nói cách khác nó chỉ định phần chuỗi xuất hiện
trong { } so với chuỗi gốc được truyền đến Console.WriteLine() hay
String.Format(). ví dụ :
Console.WriteLine("The double is {0,10:E} and the int contains {1}", d, i);
Khi tính thông số đầu tiên , {0,10:E}, hàm sẽ gọi biến double , d, và thông
số đầu tiên đưọc truyền đến nó sẽ là E. những gì
StringBuilder.AppendFormat() sẽ truyền ở đây là bất cứ đoạn văn bản nào
xuất hiện sau dấu hai chấm trong phần đặc tả định dạng từ chuỗi gốc.
Ta không quan tâm về thông số thứ 2 của Tostring().nó là 1 tham chiếu đến
đối tượng mà thực thi interface IFormatProvider.Interface này gửi thông tin
mà Tostring() có thể cần khi định dạng đối tưọng.

Quay trở lại ví dụ trên, mục đầu tiên ta muốn định dạng là double với phần
đặc tả định dạng là E.như đã đề cập , phương thức
StringBuilder.AppendFormat() sẽ thiết lập double thi hành IFormattable, và
do đó sẽ gọi hàm overload Tostring() 2 thông số,truyền vào nó chuỗi E cho
thông số đầu tiên và null cho thông số thứ hai.bây giờ nó tuỳ thuộc vào sự
thi hành của phương thức này mà sẽ trả về 1 chuỗi trình bày kiểu double
theo định dạng.
Nếu cần StringBuilder.AppendFormat() sẽ lựa chọn điền vào chuỗi trả về
với khoảng trắng, để đủ 10 kí tự trong phần đặc tả định dạng của chuỗi trong
trường hợp này.
Đối tượng kế tiếp được định dạng là kiểu int, mà không yêu cầu định dạng
cụ thể.vì vậy StringBuilder.AppendFormat() sẽ truyền vào tham chiếu null
cho định dạng chuỗi này.Toàn bộ quy trình có thể được tóm tắt như sau:

Ví dụ FormattableVector
Trong ví dụ này phần đặc tả định dạng mà ta sẽ hổ trợ là :
· N - được phiên dịch như là yêu cầu cung cấp 1 số được biết như là
Norm của Vector.là tổng bình phương của các thành phần của nó.
và luôn được trình bày giữa dấu || , ví dụ như || 34.5 ||
· VE- được phiên dịch như là yêu cầu trình bày mỗi thành phần trong
đặc tả định dạng.như đặc tả E đối với 1 số double chỉ định (2.3E+01,
4.5E+02, 1.0E+00).
· IJK - được phiên dịch như là yêu cầu trình bày vector dưới dạng 23i +
450i + 1k.
việc trình bày mặc định sẽ có dạng Vector( 23,450,1.0)
Để cho đơn giản ta sẽ không thi hành bất kì tuỳ chọn để trình bày Vector
theo kết hợp giữa IJK và định dạng khoa học.tuy nhiên ta sẽ có thể kiểm tra
đặc tả theo cách không phân biệt chữ hoa và chữ thường , để cho phép ijk
thay IJK. lưu ý rằng hoàn toàn tuỳ thuộc vào chuỗi ta sử dụng để chỉ định
đặc tả định dạng.

Đầu tiên ta sẽ khai báo Vector thi hành IFormatable:
struct Vector : IFormattable
{
public double x, y, z;
sao đó thêm vào phương thức overload tostring() 2 thông số :
public string ToString(string format, IFormatProvider formatProvider)
{
if (format == null)
return ToString();
string formatUpper = format.ToUpper();
switch (formatUpper)
{
case "N":
return "|| " + Norm().ToString() + " ||";
case "VE":
return String.Format("( {0:E}, {1:E}, {2:E} )", x, y, z);
case "IJK":
StringBuilder sb = new StringBuilder(x.ToString(), 30);
sb.Append(" i + ");
sb.Append(y.ToString());
sb.Append(" j + ");
sb.Append(z.ToString());
sb.Append(" k");
return sb.ToString();
default:
return ToString();
}
}

Đó là tất cả những gì ta phải làm. lưu ý cần kiểm tra định dạng null trước khi

gọi bất cứ phương thức nào.trong ví dụ phần đặc tả VE , ta cần mỗi thành
phần đưọc định dạng theo cú pháp khoa học,vì thế ta dùng String.Format()để
làm.tất cả các trường x,y,z là double.Trong trường hợp định dạng IJK, có vài
chuỗi con được thêm vào chuỗi , vì thế ta dùng đối tượng StringBuilder để
làm.
để hoàn chỉnh ta sẽ xây dựng lại phương thức overload Tostring() không
thông số mà ta đã phát triển ở chương 3 :
public override string ToString()
{
return "( " + x + " , " + y + " , " + z + " )";
}
cuối cùng ta thêm vào phương thức Norm() mà tính bình phương ( Norm)
của Vector :
public double Norm()
{
return x*x + y*y + z*z;
}
Bây giờ ta sẽ thử đoạn mã trên theo vài cách :
static void Main()
{
Vector v1 = new Vector(1,32,5);
Vector v2 = new Vector(845.4, 54.3, -7.8);
Console.WriteLine("\nIn IJK format,\nv1 is {0,30:IJK}\nv2 is
{1,30:IJK}",
v1, v2);
Console.WriteLine("\nIn default format,\nv1 is {0,30}\nv2 is {1,30}", v1,
v2);
Console.WriteLine("\nIn VE format\nv1 is {0,30:VE}\nv2 is {1,30:VE}",
v1,
v2);

Console.WriteLine("\nNorms are:\nv1 is {0,20:N}\nv2 is {1,20:N}", v1,
v2);
}
Kết quả trả về là :
FormattableVector
In IJK format,
v1 is 1 i + 32 j + 5 k
v2 is 845.4 i + 54.3 j + -7.8 k
In default format,
v1 is ( 1 , 32 , 5 )
v2 is ( 845.4 , 54.3 , -7.8 )
In VE format
v1 is ( 1.000000E+000, 3.200000E+001, 5.000000E+000 )
v2 is ( 8.454000E+002, 5.430000E+001, -7.800000E+000 )
Norm là :
v1 is || 1050 ||
v2 is || 717710.49 ||

×