2011-01-29 60 views
3

当为字符串解析创建自定义枚举器时,我看到一些奇怪的错误消息。当使用记录它提供了以下错误:Delphi自定义枚举器给出奇怪的错误

E2010 Incompatible types: 'TSplitStringEnumerator' and 'Pointer'

当使用类(插入代码的一些.Create电话),而不是记录我得到一些内部错误不时:

有谁知道如何保持枚举工作与记录数据类型而不是类?

type 
    TSplitStringEnumerator = record 
     StringToParse:   string; 
     Separator:    Char; 
     S:      Integer; 
     E:      Integer; 
     L:      Integer; 
     function GetCurrent (): string; inline; 
     function MoveNext (): Boolean; inline; 
     property Current: string read GetCurrent; 
    end; 

    TSplitStringGenerator = record 
     Enum:     TSplitStringEnumerator; 
     function GetEnumerator: TSplitStringEnumerator; inline; 
    end; 

function SplitString(const StringToParse: string; Separator: Char): TSplitStringGenerator; //inline; 
begin 
    Result.Enum.StringToParse := StringToParse; 
    Result.Enum.Separator  := Separator; 
    Result.Enum.S    := 0; 
    Result.Enum.E    := 0; 
    Result.Enum.L    := Length(StringToParse); 
end; 

procedure Test(); 
var 
    S: string; 
begin 
    for S in SplitString('A;B;C', ';') do begin 
     OutputDebugString(PChar(S)); 
    end; 
end; 

{ TSplitStringGenerator } 

function TSplitStringGenerator.GetEnumerator(): TSplitStringEnumerator; 
begin 
    Result := Enum; 
end; 

{ TSplitStringEnumerator } 

function TSplitStringEnumerator.GetCurrent(): string; 
begin 
    Result := Copy(StringToParse, S, E - S); 
end; 

function TSplitStringEnumerator.MoveNext(): Boolean; 
begin 
    S := E + 1; 
    Result := S <= L; 
    E := S; 
    while (E <= L) and (StringToParse[ E ] <> Separator) do Inc(E); 
end; 

回答

4

我在QC上找到了类似的bug report #72213。该漏洞在Delphi 2010中得到修复(请参阅解析注释)。

2

该代码编译,并出现在2010年德尔福为我成功运行的输出是:

Debug Output: A Process Project4.exe (4656) 
Debug Output: B Process Project4.exe (4656) 
Debug Output: C Process Project4.exe (4656) 

是否有可能与记录普查员未在2007年德尔福的支持?

+0

这很有可能。代码不能在D2009中编译,D2009肯定支持枚举器。另外,当你自己编写for in循环时(虽然`x.GetEnumerator.MoveNext`用`x.GetEnumerator.Current`做了一些事情),但它确实会编译,尽管它会陷入无限循环。还没有到处去确定这是Ritsaert示例中的代码还是编译器弄乱了它。另一方面:D2009帮助清楚地表明支持使用记录。 – 2011-01-29 17:56:53

+0

无尽循环是由GetEnumerator函数每次调用它时返回一个新的Enum成员的新初始化版本引起的?!我以为`Result:= RecordMember`将RecordMember中的内容复制到结果中?而这样做,当我改变了`x.GetEnumerator.Whatever`到`x.Enum.Whatever` ... – 2011-01-29 18:08:29