
Những chủ đề tiến bộ trong C#
Các ép kiểu do người dùng định
nghĩa – Phần 1
Trong các chương trước ta được học về cách chuyển đổi giá trị giữa những
kiểu dữ liệu cơ bản. chúng ta cũng đã học hai cách ép kiểu là :
- Không tường minh (Implicit)
- Tường minh (Explicit)
Vì c# cho phép ta định nghĩa những lớp và cấu trúc riêng,do đó ta cũng
muốn có những cách thức mà cho phép ta chuyển đổi giữa những loại dữ
liệu của riêng ta. C# cho phép làm điều đó.cơ chế của nó là ta có thể định
nghĩa một ép kiểu như là một thao tác thành viên của một trong những lớp
thích hợp. việc ép kiểu phải được đánh dấu là implicit hoặc explicit để chỉ
định cách mà bạn muốn sử dụng với nó. cũng giống như việc ép kiểu cơ bản
: nếu bạn biết việc ép kiểu là an toàn ,dù là bất cứ giá trị nào đựợc giữ bởi
biến nguồn, thì bạn định nghĩa nó như là implicit.ngược lại nếu bạn biết việc

ép kiểu có thể đi đến sự liều lĩnh - mất dữ liệu hay một biệt lệ sẽ bị tung ra -
bạn nên định nghĩa ép kiểu như là explicit.
Bạn nên định nghĩa bất kỳ kiểu ép kiểu mà bạn viết là tường minh nếu có bất
kì giá trị dữ liệu nguồn nào mà việc ép kiểu có khả năng thất bại, hoặc nếu
có sự mạo hiểm do một biệt lệ được tung ra.
Cú pháp của việc định nghĩa ép kiểu cũng giống như việc overload thao tác .
không phải ngẫu nhiên mà ta nói thế , bởi vì theo cách mà ép kiểu được xem
như là thao tác là tác động của nó là chuyển từ kiểu dữ liệu nguồn sang kiểu
dữ liệu đích. để minh hoạ cho cú pháp này, cú pháp sau được lấy từ ví dụ mà
sẽ được giới thiệu sau đây trong phần này:
public static implicit operator float (Currency value)
{
// xử lí
}
Đoạn mã này là một phần của cấu trúc - currency - được dùng để lưu trữ
tiền.ép kiểu được định nghĩa ở đây cho phép chúng ta chuyển đổi 1 cách ẩn
dụ giá trị của 1 kiểu tiền tệ sang 1 số thực ( float). chú ý rằng nếu việc
chuyển được khai báo như là implicit, thì trình biên dịch cho phép nó sử

dụng cả implicit và explicit. nếu nó được khai báo như là explicit , thì trình
biên dịch chỉ cho phép nó sử dụng như là explicit.
Trong khai báo này việc ép kiểu được khai báo là static. giống như các thao
tác được overload , C# đòi hỏi việc ép kiểu là static. điều này có nghĩa là
mỗi ép kiểu cũng lấy một thông số , mà là kiểu dữ liệu trong nguồn
Thực hành ép kiểu dữ liệu do người sử dụng định nghĩa.
Trong phần này, chúng ta sẽ xem xét việc ép kiểu implicit và explicit của
kiểu dữ liệu này trong ví dụ Simplecurrency. trong ví dụ này chúng ta định
nghĩa 1 cấu trúc struct, currency, mà giữ tiền USA. thông thường, C# cung
cấp kiểu thập phân ( decimal) cho mục đích này, nhưng bạn vẫn có thể viết
riêng 1 cấu trúc struct hay một lớp để trình bày giá trị tiền nếu bạn muốn
biểu diễn quy trình tài chính phức tạp và do đó muốn có một phương thức cụ
thể để thực thi như là một lớp.
cấu trúc của ép kiểu là giống nhau cho struct hay lớp . trong ví dụ này là
struct, nhưng nó cũng làm việc tốt nếu bạn khai báo currency như là một lớp.
khởi đầu , định nghĩa cấu trúc currency như sau:
struct Currency
{
public uint Dollars;

public ushort Cents;
public Currency(uint dollars, ushort cents)
{
this.Dollars = dollars;
this.Cents = cents;
}
Việc dùng kiểu dữ liệu không dấu cho trường Dollar và cent bảo đảm rằng
một thể hiện của currency chỉ giữ 1 số dương.chúng ta giới hạn nó bằng cách
này để có thể minh hoạ một số điểm về tường minh sau này.để giữ cho lớp
đơn giản,ta chọn các trường là public, nhưng nói chung bạn sẽ phải định
nghĩa chúng private, và định nghĩa những thuộc tính đáp ứng cho dollar và
cent
Chúng ta hãy bắt đầu bằng cách giả sử như là bạn muốn chuyển giá trị từ
currency sang float, mà phần nguyên của kiểu float sẽ trình bày dollar:
Currency balance = new Currency(10,50);
float f = balance; // ta muốn f được đặt là 10.5
Để cho phép làm điều này , cần định nghĩa 1 ép kiểu. từ đây ta thêm vào
trong cấu trúc currency:

public static implicit operator float (Currency value)
{
return value.Dollars + (value.Cents/100.0f);
}
Ép kiểu này là implicit, Đây là sự chọn lựa dễ nhận thấy , bởi vì , nó nên rõ
ràng từ định nghĩa trong currency, bất kì giá trị nào lưu trữ trong currency
cũng có thể lưu trong kiểu float.
Nếu chuyển ngược thì sao? từ một số float sang currency .trong trường hợp
này việc chuyển đổi có thể không làm việc ,nếu float lưu trữ số âm,còn
currency thì không , và số này sẽ lưu trữ phần làm tròn vào trong trường
dollar của currency.nếu float chứa đựng một giá trị không thích hợp việc
chuyển nó sẽ gây ra một kết quả không dự đoán truớc. do đó việc chuyển đổi
này nên được khai báo là explicit. sau đây là đoạn mã thử đầu tiên , tuy
nhiên nó không gửi kết quả hoàn toàn đúng:
public static explicit operator Currency (float value)
{
uint dollars = (uint)value;
ushort cents = (ushort)((value-dollars)*100);
return new Currency(dollars, cents);

