如何使用Include with Unicode?

Rol*_*son 0 delphi delphi-2007 delphi-xe2

我尝试将一些代码从D2007移植到DXE2.这个简化的代码在D2007中编译得很好.在DXE2中显示此错误:

[DCC Warning] Unit1.pas(10): W1050 WideChar reduced to byte char in set expressions.  Consider using 'CharInSet' function in 'SysUtils' unit.
[DCC Error] Unit1.pas(37): E2010 Incompatible types: 'AnsiChar' and 'Char'
Run Code Online (Sandbox Code Playgroud)

可能是一个unicode问题.有人能告诉我为什么会发生这种情况以及我该如何纠正它?

问候

代码:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TSetOfChar = Set of Char;  // Line 10

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    FCharacterSet: TSetOfChar;
  public
    property CharacterSet: TSetOfChar read FCharacterSet write FCharacterSet;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  CharacterSet: TSetOfChar;
  j: Integer;
  s: String;
begin
  CharacterSet := [];
  s := 'I''m just testing åäö';

  for j := 1 to Length(s) do
    Include(CharacterSet, s[j]);  // <- Line 37

end;

end.
Run Code Online (Sandbox Code Playgroud)

编辑:请注意,我使用的是没有泛型的Delphi 2007.我想要在D2007中仍然有效的代码,因为有很多代码要移植到Unicode.这是一个缓慢的过程.当一切都被移植,验证它适用于XE2然后我们可以使用XE2之类的东西.与此同时,我们像往常一样维护D2007,我们希望避免在修订控制系统中建立XE2分支.

Dav*_*nan 8

这是标准的Unicode Delphi迁移饲料.需要阅读的是MarcoCantù的论文 白皮书:Delphi和Unicode.如果您还没有读过,请这样做.如果您最近没有阅读过,请再次阅读.

set of char产生警告的原因是集合的基本类型不能超过256个值.但由于char现在是UTF-16,这远远超过256.这意味着你的代码永远不能使用集合和UTF-16字符.

你可以使用set of AnsiCharAnsiString.但是,如果您希望此代码处理Unicode数据,那么您将需要使用除a之外的其他内容set.例如TList<char>可以使用.

var
  CharacterSet: TList<char>;
  s: string;
  c: char;
.....
CharacterSet := TList<char>.Create;
s := 'I''m just testing åäö';
for c in s do
  if not CharacterSet.Contains(c) then
    CharacterSet.Add(c);
Run Code Online (Sandbox Code Playgroud)

我不建议用于生产.它的性能特征会很糟糕.基于哈希的字典会做得更好.最重要的是一个专门的大型课程.

最后一点.字符与UTF-16中的代码点不同,后者是可变长度编码.有问题的代码和这个答案不予考虑.