2012-02-27 10 views
12

Ho controllato la classe TDataset e i relativi campi stringa in Delphi XE2 e ho notato che AsWideString restituisce un tipo di UnicodeString. Tuttavia ottiene il valore dalla funzione TField.AsString: String che a sua volta chiama TFIeld.AsAnsiString: AnsiString. Quindi tutti i caratteri Unicode andrebbero persi? Anche il buffer passato a TDataset.GetFieldData è dichiarato come una matrice di AnsiChar.Delphi XE2 Tipo di campo del set di dati TStringField non supporta Unicode?

Sto comprendendo questo correttamente?

+1

+1 Dal momento che questo comportamento è IMHO un'implementazione errata VCL. È IMHO una denominazione errata, * incoerente con il resto VCL/RTL * e una fonte di molta confusione/incomprensione. La tua domanda ha perfettamente senso. –

risposta

12

No, si dovrebbe esaminare la classe TWideStringField che è per i campi Unicode e la classe TStringField che è per le stringhe non Unicode. TField è solo una classe base e TField.GetAsWideString è un metodo virtuale con un'implementazione fallback che viene sovrascritta dai discendenti che sono a conoscenza di Unicode.

+1

Effetto collaterale di due classi di campi stringa: le migrazioni di database a Unicode richiedono la sostituzione di TStringField in DFM con TWideStringField (e molte altre modifiche al codice sorgente), in cui gli sviluppatori si aspettano una transizione uniforme – mjn

+3

@mjn, questo approccio consentirà di effettuare passaggio a unicode nella tua app senza modificare i campi del database sottostante.TWideStringField è in circolazione da anni e non è collegato a Delphi passando a Unicode. Se il campo nel database è stato unicode in precedenza, è già stato necessario utilizzare TWideStringField comunque in Delphi 5. Si utilizza TStringField se il campo del database è solo AnsiString. Delphi non cambierà automaticamente la definizione dei dati e i dati nel database. –

+1

@mjn In realtà no poiché normalmente dipende dal database se il valore è unicode o no. Quindi se il tuo database era unicode nella vecchia versione di Delphi era già TWideStringField. Se no, perché dovrebbe essere nella versione più recente se il database non ha ancora unicode? –

4

Sì, lo hai capito correttamente. Questo è il VCL e la sua documentazione che sono guasti. La tua confusione ha perfettamente senso!

Nel Delphi 2009+ implementazione, è necessario utilizzare AsString immobili per AnsiString e AsWideString per string=UnicodeString.

Infatti, le As*String proprietà sono definite come tali:

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

Come diavolo possiamo essere in grado di scoprire che AsString restituisce un AnsiString? Semplicemente non ha alcun senso, se confrontato con il resto della VCL/RTL.

L'implementazione, che utilizza la classe TStringField per AnsiString e TWideStringField per string=UnicodeString è danneggiata.

Inoltre, il documentation is also broken:

Data.DB.TField.AsString

Rappresenta il valore del campo come stringa (Delphi) o un AnsiString (C++).

Questo non rappresenta una string in Delphi, ma un AnsiString! Il fatto che la proprietà usi un semplice tipo string=UnicodeString è assolutamente fuorilegge.

Dal punto di vista del database, spetta al driver DB gestire Unicode o lavorare con un set di caratteri specifico. Ma dal punto di vista della VCL, in Delphi 2009+ dovresti conoscere solo il tipo string e confidare che l'utilizzo di AsString: String sarà pronto per Unicode.

Problemi correlati