Delphi 如何区分旧式的object和record? 程序项目15; {$APPTYPE控制台} {$R*.res} 使用 System.Rtti、System.TypInfo; 类型 记录 公众的 AField:整数; 构造函数初始化(测试:整数); 结束; TOldObject=对象 公众的 AField:整数; 构造函数初始化(测试:整数); 程序幻想;虚拟的
旧对象已弃用 因此,您不应该将其与新的rtti结合使用 反对的第一步是禁止虚拟方法。我想是因为编译器的回归Delphi 如何区分旧式的object和record? 程序项目15; {$APPTYPE控制台} {$R*.res} 使用 System.Rtti、System.TypInfo; 类型 记录 公众的 AField:整数; 构造函数初始化(测试:整数); 结束; TOldObject=对象 公众的 AField:整数; 构造函数初始化(测试:整数); 程序幻想;虚拟的,delphi,delphi-xe2,rtti,Delphi,Delphi Xe2,Rtti,旧对象已弃用 因此,您不应该将其与新的rtti结合使用 反对的第一步是禁止虚拟方法。我想是因为编译器的回归 这是Embarcadero模仿C#及其结构/类范式的决定。错误的决策imho。据我所知,在Delphi的RTTI框架中,旧式对象无法与记录区分开来。这个节目 program Project15; {$APPTYPE CONSOLE} {$R *.res} uses System.Rtti, System.TypInfo; type TRecord = record pub
这是Embarcadero模仿C#及其结构/类范式的决定。错误的决策imho。据我所知,在Delphi的RTTI框架中,旧式对象无法与记录区分开来。这个节目
program Project15;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.Rtti, System.TypInfo;
type
TRecord = record
public
AField: integer;
constructor Init(test: integer);
end;
TOldObject = object
public
AField: integer;
constructor Init(test: integer);
procedure Fancy; virtual; <<--- compiles
class operator Implicit(test: TRecord): TOldObject; <<-- does not compile.
end;
procedure IsObjectARecord;
var
ARecord: TRecord;
AObject: TOldObject;
v: TValue;
s: String;
begin
v:= TValue.From(ARecord);
case v.Kind of
tkRecord: WriteLn('it''s a Record');
end;
ARecord:= TRecord.Init(10);
AObject.Init(10);
v:= TValue.From(AObject);
case v.Kind of
tkRecord: begin
WriteLn('object is a record?');
if v.IsObject then s:= 'true'
else s:= 'false';
WriteLn('isObject = ' + s);
WriteLn('ToString says: '+v.ToString);
end;
end;
end;
{ TOldSkool }
constructor TOldObject.Init(test: integer);
begin
AField:= 10;
end;
constructor TRecord.Init(test: integer);
begin
AField:= 10;
end;
begin
IsObjectARecord;
Readln;
end.
输出
{$APPTYPE CONSOLE}
uses
System.Rtti;
type
TOldObject = object
end;
var
ctx: TRttiContext;
RttiType: TRttiType;
begin
RttiType := ctx.GetType(TypeInfo(TOldObject));
Writeln(TValue.From(RttiType.TypeKind).ToString);
Writeln(RttiType.IsRecord);
Readln;
end.
tkRecord
真的
对象的实例可以存在于堆栈或堆上。与records.FWIW一样,如果将冒号转换为分号,虚拟方法将编译。注意,您的语法错误不会编译,但虚拟方法会编译(在XE4中测试)。运算符未按预期编译。谢谢Rudy;吸取的教训;当咖啡因含量低时不要编码@Arnaud这并没有回答所问的问题。你应该把它变成一个注释。这确实应该是一个注释,虚拟方法是不允许的。该行中有一个语法错误,这就是它无法编译的原因。所以不要告诉我它仍然可用。IMHO我回答了关于rtti的问题:对象不再被使用,所以新的rtti不支持它,旧的rtti也不支持它,因为它已经专注于类。@Johan,因为你应该在2014年使用object
,如果你想扩展并发编程,就像你对像Rust这样的现代语言所做的那样,请看@ArnaudBouchez,你回答了一个不同的问题。您回答:“我应该使用对象吗?”
tkRecord
TRUE