2012-02-27 15 views
12

Tôi đã xem qua lớp TDataset và các trường chuỗi của nó, trong Delphi XE2 và nhận thấy rằng AsWideString trả về một kiểu UnicodeString. Tuy nhiên nó nhận được giá trị từ hàm TField.AsString: String mà lần lượt gọi TFIeld.AsAnsiString: AnsiString. Vì vậy, bất kỳ ký tự unicode sẽ bị mất? Ngoài ra bộ đệm được chuyển đến TDataset.GetFieldData được khai báo là một mảng của AnsiChar.Loại trường dữ liệu Delphi XE2 Dataset TStringField không hỗ trợ Unicode?

Tôi có hiểu chính xác điều này không?

+1

+1 Vì hành vi này là IMHO, việc triển khai sai VCL. Đó là IMHO một tên sai, * không phù hợp với phần còn lại của VCL/RTL * và một nguồn rất nhiều nhầm lẫn/hiểu lầm. Câu hỏi của bạn hoàn toàn có ý nghĩa. –

Trả lời

12

Không, bạn nên kiểm tra lớp TWideStringField dành cho các trường Unicode và lớp TStringField dành cho các chuỗi không phải Unicode. TField chỉ là một lớp cơ sở và TField.GetAsWideString là một phương pháp ảo với một thực hiện giảm trở lại được ghi đè bởi hậu duệ được nhận thức Unicode.

+1

Hiệu ứng phụ tốt đẹp của việc có hai lớp chuỗi: chuyển đổi cơ sở dữ liệu sang Unicode yêu cầu thay thế tất cả TStringField trong DFM bằng TWideStringField (và nhiều thay đổi mã nguồn khác), nơi các nhà phát triển mong đợi một chuyển đổi trơn tru – mjn

+3

@mjn, cách tiếp cận này sẽ cho phép bạn thực hiện chuyển sang unicode trong ứng dụng của bạn mà không thay đổi các trường cơ sở dữ liệu cơ bản.TWideStringField đã tồn tại nhiều năm và không liên quan đến việc chuyển đổi sang Delphi sang Unicode. Nếu trường trong cơ sở dữ liệu đã được unicode trước, bạn đã phải sử dụng TWideStringField trong nói Delphi 5 anyway. Bạn sử dụng TStringField nếu trường cơ sở dữ liệu chỉ là AnsiString. Delphi sẽ không thay đổi định nghĩa dữ liệu và dữ liệu của bạn trong cơ sở dữ liệu một cách tự động. –

+1

@mjn Trên thực tế không kể từ bình thường nó phụ thuộc vào cơ sở dữ liệu nếu giá trị là unicode hay không. Vì vậy, nếu cơ sở dữ liệu của bạn đã được unicode trong phiên bản Delphi cũ nó đã được TWideStringField rồi. Nếu không phải lý do tại sao nó nên được trong phiên bản mới hơn nếu cơ sở dữ liệu vẫn không có unicode? –

4

CÓ, bạn đã hiểu chính xác. Đây là VCL và tài liệu của nó bị hỏng. Sự nhầm lẫn của bạn hoàn toàn có ý nghĩa!

Trong triển khai Delphi 2009+, bạn phải sử dụng thuộc tính AsString cho AnsiStringAsWideString cho string=UnicodeString.

Trong thực tế, As*String thuộc tính được định nghĩa như vậy:

property AsString: string read GetAsString write SetAsString; 
property AsWideString: UnicodeString read GetAsWideString write SetAsWideString; 
property AsAnsiString: AnsiString read GetAsAnsiString write SetAsAnsiString; 

Làm thế nào trên trái đất chúng ta có thể tìm ra rằng AsString trả về một AnsiString? Nó chỉ không có ý nghĩa gì cả, khi so sánh với phần còn lại của VCL/RTL.

Việc triển khai, sử dụng lớp TStringField cho AnsiStringTWideStringField cho string=UnicodeString bị hỏng.

Hơn nữa, documentation is also broken:

Data.DB.TField.AsString

Đại diện cho giá trị của lĩnh vực như là một chuỗi (Delphi) hoặc một AnsiString (C++).

Điều này không đại diện cho string ở Delphi, nhưng AnsiString! Thực tế là tài sản sử dụng một loại đồng bằng string=UnicodeString là hoàn toàn bỏ lỡ.

Trên quan điểm cơ sở dữ liệu, điều đó tùy thuộc vào trình điều khiển DB để xử lý Unicode hoặc làm việc với bộ ký tự cụ thể. Nhưng trên quan điểm VCL, trong Delphi 2009+ bạn chỉ nên biết về loại string và tự tin rằng việc sử dụng AsString: String sẽ sẵn sàng với Unicode.