2009-07-13 39 views
15

夏天的商业气氛已经开始,所以我选择了迁移到D2009。我大致确定了程序的每个子系统是否应该保持ascii,或者可以是unicode,并开始移植。D2009 TStringlist ansistring

它非常好,所有的组件都在D2009版本(有些像VSTView,虽然稍微不兼容),但我现在遇到了问题,在某些部分必须保持ansistring,我广泛使用TStringList,主要是一张基本地图。

是否已有一些容易来取代它,或者我应该简单地包括砍下AnsiString类型的TStringList,基于旧Delphi或FPC源?

我无法想象我是第一次碰到这个?

的变化必须相对定位,使代码保持编译与BDS2006而我经过验证的轨迹。一些ifdefs在这里和那里都没有问题。 当然string-> ansistring和char - > ansichar等在我的源代码中并不算作修改,因为无论如何我必须这样做,而且完全向后兼容。

编辑:我已经能够工作远一些的东西在读/写器类。这使得梅森解决方案比我原先想象的更容易。我会认为Gabr的建议是回退。

泛型是相当多的,我买D2009的原因。遗憾的是,他们把它FPC不相容虽然

+1

您是否正在进行大量计算,包括字符串的字节数和字符串的长度?因为这是我做出这种降级的唯一真正要求。 – smok1 2009-07-13 14:57:27

+0

一个是,版本化向后兼容的二进制版本。另一个(我还没有开始)是一个定制的Sax和DOM实现。 但主要原因是我不想向客户解释如何用记事本和excel打开Unicode文本文件等,并保持原来的旧,简单的旧。 – 2009-07-13 15:21:56

+1

我再次被用户在SO上的行为困惑。有五位用户对这个问题给出了深思熟虑的答案,至少有71位观众收到了14票,但还没有人投票赞成这个问题。没有问题是完美的,但我发现阅读Q和As - so +1是有帮助的。恕我直言,**支持德尔福**包括支持有关该主题的信息性讨论。 – Argalatyr 2009-07-13 18:26:01

回答

9

如果“映射”你的意思是“哈希表”,你可以用普通的TDictionary更换。尝试声明如下:

uses 
    Generics.Collections; 

type 
    TStringMap<T: class> = TDictionary<ansiString, T>; 

然后,只需将您的StringLists替换为正确的对象类型的TStringMaps即可。 (更好的类型安全性是免费的。)另外,如果您希望字典拥有这些对象并在完成时释放它们,请将其更改为TObjectDictionary,然后在调用构造函数时将[doOwnsValues]传递给适当的参数。

(顺便说一句,如果你要使用TDictionary,请确保您下载D2009更新3.原始版本曾在TDictionary,使得它几乎无法使用一些严重的错误)

编辑:如果仍然有在D2006下编译,那么你将不得不调整一些东西。尝试这样的:

type 
    TStringMap = 
{$IFDEF UNICODE} 
    class TDictionary<ansiString, TObject> 
    (Add some basic wrapper functions here.) 
    end; 
{$ELSE} 
    TStringList; 
{$ENDIF} 

如果你首先使用它作为地图,包装不应该花费太多的工作。为了向后兼容,你失去了额外的安全类型,但是你获得了一个真正的哈希表,它在O(1)时间内进行查找。

3

做这些子系统需要保持AnsiString类型,或只是如何与外界沟通(RS232,文本文件等)?就像我在C#中所做的一样,我将Delphi 2009中的字符串视为字符串,只在其他人需要时才担心转换。

这也将有助于避免你的代码,调用Windows API的方法时,提高性能无意的隐式转换。

+0

文本文件,RS232是正确的。然而,持久性不仅仅是stringlist.savetostream,而是用严格的版本向后兼容性要求进行手动编码。我粗略的做了同样的建议,但我宁愿保留输入/输出ansistrings的子系统并在内部严格使用它们,避免麻烦。之后,在迁移后,我将选定的部分更新为ansistring。 – 2009-07-13 15:17:56

2

您可以修改德尔福2007年(或更早)的字符串列表和的TStringList类,并将其重命名为TAnsiStrings和TAnsiStringList。你应该发现这是一个非常简单的修改,并且会给你所需要的类。

12

JCL在JclAnsiStrings单元中实现TAnsiStrings和TAnsiStringList。

8

TStringList.LoadFromFile/SaveToFile也带一个类型为TEncoding的可选参数,它允许你使用TStringList来存储你想要的任何类型的字符串。

procedure LoadFromFile(const FileName: string; Encoding: TEncoding); overload; virtual; 
procedure SaveToFile(const FileName: string; Encoding: TEncoding); overload; virtual; 

还要注意,在默认情况下,使用TStringList中作为ANSI代码页,使所有现有代码的工作,因为它有。