2012-02-27 12 views
12

Przeglądałem klasę TDataset i jej pola tekstowe w Delphi XE2 i zauważyłem, że AsWideString zwraca typ UnicodeString. Jednak pobiera wartość z funkcji TField.AsString: String, która z kolei wywołuje TFIeld.AsAnsiString: AnsiString. Dlatego wszystkie znaki unicode zostaną utracone? Również bufor przekazywany do TDataset.GetFieldData jest zadeklarowany jako tablica AnsiChar.Delphi XE2 Typ pola zestawu danych TStringField nie obsługuje standardu Unicode?

Czy rozumiem to poprawnie?

+1

+1 Ponieważ takie zachowanie to IMHO, błędna implementacja VCL. Jest to błędne nazewnictwo IMHO, * niezgodne z resztą VCL/RTL * i źródłem wielu nieporozumień/nieporozumień. Twoje pytanie ma sens. –

Odpowiedz

12

Nie, powinieneś badać klasę TWideStringField dla pól Unicode i klasy TStringField dla łańcuchów innych niż Unicode. TField to tylko klasa podstawowa, a TField.GetAsWideString to metoda wirtualna z implementacją wycofania, która jest nadpisywana przez potomków, którzy są świadomi Unicode.

+1

Miły efekt uboczny posiadania dwóch klas pól tekstowych: migracja baz danych do Unicode wymaga zastąpienia wszystkich TStringField w DFM za pomocą TWideStringField (i wielu innych zmian kodu źródłowego), gdzie programiści oczekują płynnego przejścia – mjn

+3

@mjn, to podejście pozwoli ci stworzyć przejście do unicodu w aplikacji bez zmiany podstawowych pól bazy danych.TWideStringField istnieje od lat i nie jest związany z przełączaniem Delphi na Unicode. Jeśli pole w bazie danych było wcześniej w Unicode, musieliście już używać TWideStringField, na przykład Delphi 5. Używasz TStringField, jeśli pole bazy danych to tylko AnsiString. Delphi nie zmieni automagicznie definicji danych i danych w bazie danych. –

+1

@mjn Właściwie nie, ponieważ normalnie zależy to od bazy danych, jeśli wartością jest unikod lub nie. Więc jeśli twoja baza danych zawierała unicode w starej wersji Delphi, to już był TWideStringField. Jeśli nie, dlaczego miałby być w nowszej wersji, jeśli baza danych nadal nie ma kodu Unicode? –

4

TAK, zrozumiałeś to poprawnie. To jest VCL i jego dokumentacja, które są zepsute. Twoje zamieszanie ma sens!

W 2009+ realizacji Delphi, trzeba użyć AsString nieruchomość za AnsiString i AsWideString dla string=UnicodeString.

W rzeczywistości, właściwości As*String są zdefiniowane jako takie:

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

Jak na ziemi, być może będziemy mogli dowiedzieć się, że AsString zwraca AnsiString? To po prostu nie ma sensu, w porównaniu do reszty VCL/RTL.

Implementacja, która używa klasy TStringField dla AnsiString i TWideStringField dla string=UnicodeString jest zepsuta.

Ponadto documentation is also broken:

Data.DB.TField.AsString

reprezentuje wartość pola jako łańcuch (Delphi) lub AnsiString (C++).

nie stanowią string w Delphi, ale AnsiString! Fakt, że nieruchomość posługuje się zwykłym typem string=UnicodeString, jest całkowicie zwodniczy.

Z punktu widzenia bazy danych, do sterownika DB należy obsługa Unicode lub praca z określonym zestawem znaków. Ale z punktu widzenia VCL, w Delphi 2009+ powinieneś wiedzieć tylko o typie string i mieć pewność, że użycie AsString: String będzie gotowe do obsługi Unicode.