我一直在查看 Delphi XE2 中的 TDataset 类及其字符串字段,并注意到 AsWideString 返回一个 UnicodeString 类型。然而,它从函数 TField.AsString:String 中获取值,该函数又调用 TFIeld.AsAnsiString:AnsiString。因此任何 unicode 字符都会丢失?传递给 TDataset.GetFieldData 的缓冲区也被声明为 AnsiChar 数组。
我是否正确理解这一点?
我一直在查看 Delphi XE2 中的 TDataset 类及其字符串字段,并注意到 AsWideString 返回一个 UnicodeString 类型。然而,它从函数 TField.AsString:String 中获取值,该函数又调用 TFIeld.AsAnsiString:AnsiString。因此任何 unicode 字符都会丢失?传递给 TDataset.GetFieldData 的缓冲区也被声明为 AnsiChar 数组。
我是否正确理解这一点?
不,您应该检查用于 Unicode 字段的TWideStringField类和用于非 Unicode 字符串的TStringField类。TField只是一个基类,而TField.GetAsWideString是一个具有后备实现的虚拟方法,它被支持 Unicode 的后代覆盖。
是的,您确实理解正确。这是损坏的 VCL 及其文档。你的困惑完全有道理!
在 Delphi 2009+ 实现中,您必须使用AsString
属性 forAnsiString
和AsWideString
for string=UnicodeString
。
实际上,As*String
属性是这样定义的:
property AsString: string read GetAsString write SetAsString;
property AsWideString: UnicodeString read GetAsWideString write SetAsWideString;
property AsAnsiString: AnsiString read GetAsAnsiString write SetAsAnsiString;
我们到底怎么能找出AsString
返回一个AnsiString
?与 VCL/RTL 的其余部分相比,它根本没有意义。
使用TStringField
类 forAnsiString
和TWideStringField
for的实现string=UnicodeString
被破坏了。
此外,文档也被破坏了:
数据.DB.TField.AsString
将字段的值表示为字符串 (Delphi) 或 AnsiString (C++)。
string
这在 Delphi中不代表 a ,而是代表AnsiString
! 该属性使用普通string=UnicodeString
类型的事实完全具有误导性。
从数据库的角度来看,由 DB 驱动程序来处理 Unicode 或使用特定的字符集。但是从 VCL 的角度来看,在 Delphi 2009+ 中,您应该只知道string
类型,并且确信使用AsString: String
将支持 Unicode。