Delphi 编译器错误?使用 "object",但使用 "record" 编译
Delphi compiler bug? using "object", but with "record" it compiles
此代码无法编译(在 Delphi 7 和 Delphi XE2 上),并给出错误消息“E2036 需要变量”。
但是,如果我将“对象”更改为“记录”,那么它在 Delphi XE2 上编译得很好,因为它有高级记录。
我想在 Delphi 版本之间编写可移植代码,并在 D7 上使用“object”,在 XE2 上使用 IFDEF 使用“record”,但在这种情况下看起来不可能。我错了吗,或者这是一个真正的编译器错误?
type
TD = String;
TC = object
public
V: String;
function D: TD;
end;
TB = object
public
V: String;
function C: TC;
end;
TA = object
public
V: String;
function B: TB;
end;
function TC.D: TD; begin end;
function TB.C: TC; begin end;
function TA.B: TB; begin end;
procedure Test;
var
A: TA;
s: string;
begin
s := A.V; // Ok
s := A.B.V; // Ok
s := A.B.C.V; // "E2036 Variable required", the cursor is between "C" and "."
end;
感谢大家的快速响应。令人惊讶的是,几分钟后我找到了解决方法。 “对象”必须至少有一个虚拟方法(并且它的大小不能为零,所以它必须有一个数据字段,但它不必像“V:string”那样是托管类型)。这段丑陋的代码可以在 Delphi 7 上编译,也可以在 Delphi XE2 上编译,如果
HAS_ADVANCEDRECORD 已定义。
{.$define HAS_ADVANCEDRECORD}
type
TE = String;
TD = {$ifdef HAS_ADVANCEDRECORD}record{$else}object{$endif}
public
V: String;
function E: TE; {$ifndef HAS_ADVANCEDRECORD}virtual;{$endif}
end;
TC = {$ifdef HAS_ADVANCEDRECORD}record{$else}object{$endif}
public
V: String;
function D: TD; {$ifndef HAS_ADVANCEDRECORD}virtual;{$endif}
end;
TB = {$ifdef HAS_ADVANCEDRECORD}record{$else}object{$endif}
public
V: String;
function C: TC; {$ifndef HAS_ADVANCEDRECORD}virtual;{$endif}
end;
TA = {$ifdef HAS_ADVANCEDRECORD}record{$else}object{$endif}
public
V: String;
function B: TB; {$ifndef HAS_ADVANCEDRECORD}virtual;{$endif}
end;
function TD.E: TE; begin end;
function TC.D: TD; begin end;
function TB.C: TC; begin end;
function TA.B: TB; begin end;
procedure Test;
var
A: TA;
s: string;
begin
s := A.V; //* Ok
s := A.B.V; //* Ok
s := A.B.C.D.E; //* Solved: "E2036 Variable required"
end;
实际上我想玩一个流畅的语法 sql 查询生成器,高级记录比 TObject 有优势。也就是说,它们不需要生命周期管理。一个自然的解决方案是在这里使用接口,但我总是遇到麻烦。
我想,更值得提高我对界面的了解...
这是一个错误。您可以提交错误报告,该报告至少会对其进行记录。但是,我严重怀疑 Embarcadero 是否会投入更多资源来修复它,无论如何这对您的旧版本 Delphi.
没有帮助
此代码无法编译(在 Delphi 7 和 Delphi XE2 上),并给出错误消息“E2036 需要变量”。 但是,如果我将“对象”更改为“记录”,那么它在 Delphi XE2 上编译得很好,因为它有高级记录。 我想在 Delphi 版本之间编写可移植代码,并在 D7 上使用“object”,在 XE2 上使用 IFDEF 使用“record”,但在这种情况下看起来不可能。我错了吗,或者这是一个真正的编译器错误?
type
TD = String;
TC = object
public
V: String;
function D: TD;
end;
TB = object
public
V: String;
function C: TC;
end;
TA = object
public
V: String;
function B: TB;
end;
function TC.D: TD; begin end;
function TB.C: TC; begin end;
function TA.B: TB; begin end;
procedure Test;
var
A: TA;
s: string;
begin
s := A.V; // Ok
s := A.B.V; // Ok
s := A.B.C.V; // "E2036 Variable required", the cursor is between "C" and "."
end;
感谢大家的快速响应。令人惊讶的是,几分钟后我找到了解决方法。 “对象”必须至少有一个虚拟方法(并且它的大小不能为零,所以它必须有一个数据字段,但它不必像“V:string”那样是托管类型)。这段丑陋的代码可以在 Delphi 7 上编译,也可以在 Delphi XE2 上编译,如果 HAS_ADVANCEDRECORD 已定义。
{.$define HAS_ADVANCEDRECORD}
type
TE = String;
TD = {$ifdef HAS_ADVANCEDRECORD}record{$else}object{$endif}
public
V: String;
function E: TE; {$ifndef HAS_ADVANCEDRECORD}virtual;{$endif}
end;
TC = {$ifdef HAS_ADVANCEDRECORD}record{$else}object{$endif}
public
V: String;
function D: TD; {$ifndef HAS_ADVANCEDRECORD}virtual;{$endif}
end;
TB = {$ifdef HAS_ADVANCEDRECORD}record{$else}object{$endif}
public
V: String;
function C: TC; {$ifndef HAS_ADVANCEDRECORD}virtual;{$endif}
end;
TA = {$ifdef HAS_ADVANCEDRECORD}record{$else}object{$endif}
public
V: String;
function B: TB; {$ifndef HAS_ADVANCEDRECORD}virtual;{$endif}
end;
function TD.E: TE; begin end;
function TC.D: TD; begin end;
function TB.C: TC; begin end;
function TA.B: TB; begin end;
procedure Test;
var
A: TA;
s: string;
begin
s := A.V; //* Ok
s := A.B.V; //* Ok
s := A.B.C.D.E; //* Solved: "E2036 Variable required"
end;
实际上我想玩一个流畅的语法 sql 查询生成器,高级记录比 TObject 有优势。也就是说,它们不需要生命周期管理。一个自然的解决方案是在这里使用接口,但我总是遇到麻烦。
我想,更值得提高我对界面的了解...
这是一个错误。您可以提交错误报告,该报告至少会对其进行记录。但是,我严重怀疑 Embarcadero 是否会投入更多资源来修复它,无论如何这对您的旧版本 Delphi.
没有帮助