2012-02-27 92 views
12

我一直在寻找通过TDataset类和它的字符串领域,在Delphi XE2中,并注意到AsWideString返回一种UnicodeString类型。但是,它从函数TField.AsString:String获取值,该函数继而调用TFIeld.AsAnsiString:AnsiString。因此,任何unicode字符都会丢失?此外,传递给TDataset.GetFieldData的缓冲区被声明为AnsiChar的数组。德尔福XE2数据集字段类型TStringField不支持Unicode?

我能理解这个吗?

+1

+1由于此行为是恕我直言的VCL错误的实施。这是恕我直言,一个错误的命名,*不符合其余的VCL/RTL *和一个混乱/误解很多的来源。你的问题确实很有意义。 – 2013-04-22 05:21:25

回答

12

不,您应该检查用于Unicode字段的TWideStringField类和用于非Unicode字符串的TStringField类。 TField只是一个基类,而TField.GetAsWideString是一个具有回退实现的虚拟方法,可以被支持Unicode的后代覆盖。

+1

有两个字符串字段类的好的副作用:数据库迁移到Unicode需要使用TWideStringField(以及许多其他源代码更改)替换DFM中的所有TStringField,其中开发人员期望平滑过渡 – mjn 2012-02-27 06:27:50

+3

@mjn,此方法将使您在您的应用程序中转换为unicode,而无需更改基础数据库字段。TWideStringField已经存在多年,与Delphi切换到Unicode无关。如果数据库中的字段之前是unicode,那么无论如何,你已经必须在Delphi 5中使用TWideStringField。如果数据库字段只是一个AnsiString,则使用TStringField。 Delphi不会自动更改数据定义和数据库中的数据。 – 2012-02-27 08:26:26

+1

@mjn实际上没有,因为通常它取决于数据库,如果该值是unicode或不。所以如果你的数据库在旧的Delphi版本中是unicode,那么它已经是TWideStringField了。如果不是为什么它应该在新版本中,如果数据库还没有unicode? – 2012-02-27 08:37:39

4

是的,你的确理解正确。这是VCL及其文档,它们被破坏。你的困惑确实很有道理!

在Delphi 2009+执行,你必须使用AsString财产为AnsiStringAsWideStringstring=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类别AnsiStringTWideStringField对于string=UnicodeString已被破坏。

此外,documentation is also broken

Data.DB.TField.AsString

表示为一个字符串(DELPHI)或AnsiString类型(C++)字段的值。

这不代表在Delphi中的string,而是AnsiString!该物业使用普通string=UnicodeString类型的事实完全是令人迷惑的。

从数据库的角度来看,数据库驱动程序需要处理Unicode或使用特定的字符集。但从VCL的角度来看,在Delphi 2009+中,你应该只知道string类型,并且确信使用AsString: String将会是Unicode准备好的。