Reputation: 59
I have the following code
type
TEnumTest = (
Hello1 = 0,
Hello2 = 1,
Hello3 = 2,
Hello4 = 3,
Hello5 = 4
);
type
TRecordTest1 = record
testa : Integer;
testb : AnsiString;
testc : Boolean;
testd : LongWord;
end;
type
TRecordTest2 = record
testa : Integer;
testb : AnsiString;
testc : Boolean;
testd : TEnumTest;
end;
type
TRecordTest3 = record
testa : Integer;
testb : AnsiString;
testc : Boolean;
testd : TEnumTest;
end;
type
TRecordTest4 = record
testa : Integer;
testb : AnsiString;
testc : Boolean;
testd : TEnumTest;
end;
type
TtestRecord = record
test1 : TRecordTest1;
test2 : TRecordTest2;
test3 : TRecordTest3;
test4 : TRecordTest4;
end;
Is there a way by using reflection or other mechanism so I can do operations such as:
var
a : TtestRecord;
b : TtestRecord;
if a = b then
begin
..............
..............
end;
clearAllValues(a);
I just added the logical expression
Upvotes: 2
Views: 1637
Reputation: 596196
The compiler knows how to assign one record to another, so you don't need to do anything special for that. On the other hand, if you want to compare records, you have to implement that manually.
For clearing a record in a general manner, that can be done in Delphi 2010+ using Extended RTTI. But it would be a lot of manual coding. The compiler already knows how to initialize a record, especially when it contains any compiler-managed types, like strings. Let the compiler utilize that reflection for you, eg:
var
a : TtestRecord;
b : TtestRecord;
begin
a := b;
a := Default(TtestRecord);
end;
Upvotes: 1
Reputation: 43033
You can use the Record*()
functions, available in our Open Source SynCommons.pas unit.
You would be able to write:
var
a : TtestRecord;
b : TtestRecord;
...
if RecordEquals(a,b,TypeInfo(TtestRecord)) then
writeln('a=b');
RecordClear(a,TypeInfo(TtestRecord));
...
You have a lot of additional functions, like fast binary or JSON serialization.
var tmp: RawByteString;
json: RawUTF8;
...
tmp := RecordSave(a,TypeInfo(TtestRecord));
...
RecordLoad(b,pointer(tmp),TypeInfo(TtestRecord));
...
json := RecordSaveJSON(a,TypeInfo(TtestRecord));
RecordLoadJSON(b,pointer(json),TypeInfo(TtestRecord));
...
Since Delphi 2010, the JSON serialization will use advanced RTTI. Before Delphi 2010, you just have to register the type using some text.
So this features works from Delphi 6 up to XE8, and also with FreePascal.
As reference, take a look at the corresponding documentation of our framework.
Upvotes: 0
Reputation: 612954
Comparing two records for equality
You could certainly use RTTI to perform comparisons of records. However, I think I would do that by using extended records with comparison operators. For instance:
type
TMyRecord = record
i: Integer;
s: string;
class operator Equal(const lhs, rhs: TMyRecord): Boolean;
class operator NotEqual(const lhs, rhs: TMyRecord): Boolean;
end;
class operator TMyRecord.Equal(const lhs, rhs: TMyRecord): Boolean;
begin
Result := (lhs.i = rhs.i) and (lhs.s = rhs.s);
end;
class operator TMyRecord.NotEqual(const lhs, rhs: TMyRecord): Boolean;
begin
Result := not (lhs = rhs);
end;
Clearing a record
You can use the intrinsic function Default
to default initialize any type. I'd include a documentation link, but this function is, sadly, undocumented.
You would write your code like this:
var
a: TTestRecord;
...
a := Default(TTestRecord); // a is replaced with default initialized value
The undocumented Default
function takes a type identifier as its argument, and returns a default initialized instance of that type. So, numeric types are initialized to zero, strings to ''
, pointers to nil
, etc.
Upvotes: 4