使用成员函数
到目前为止,最简洁的方法,恕我直言,是声明一个方法TDummy.IsEmpty: Boolean:
type
TDummy = record
Text: string;
Number: Integer;
function IsEmpty: Boolean;
end;
{ TDummy }
function TDummy.IsEmpty: Boolean;
begin
Result := (Text = '') and (Number = 0);
end;
那么你可以随时使用这个方法来查看记录是否为空:
procedure TForm1.FormCreate(Sender: TObject);
var
D: TDummy;
begin
D := Default(TDummy);
if D.IsEmpty then
ShowMessage('D is empty.');
D.Number := 394;
if D.IsEmpty then
ShowMessage('D is empty.');
end;
使用等于运算符
另一种方法:
type
TDummy = record
Text: string;
Number: Integer;
class operator Equal(const Left, Right: TDummy): Boolean;
class operator NotEqual(const Left, Right: TDummy): Boolean;
end;
const
EmptyDummy: TDummy = ();
{ TDummy }
class operator TDummy.Equal(const Left, Right: TDummy): Boolean;
begin
Result := (Left.Text = Right.Text) and (Left.Number = Right.Number);
end;
class operator TDummy.NotEqual(const Left, Right: TDummy): Boolean;
begin
Result := not (Left = Right);
end;
现在你可以做
procedure TForm1.FormCreate(Sender: TObject);
var
D: TDummy;
begin
D := Default(TDummy);
if D = EmptyDummy then
ShowMessage('D is empty.');
D.Number := 394;
if D = EmptyDummy then
ShowMessage('D is empty.');
end;
疯狂的东西
如果您绝对不想单独比较每个成员,您可以在某些情况下比较字节。
但请注意,一般情况下,您不能通过比较它们的字节来比较两条记录。只提两个明显的原因:
-
字符串成员在语义上可能是相等的,即使它们由两个不同的字符串堆对象表示(因此比较器说“不相等”而实际上它们是相等的)。
-
如果记录不是packed,则记录可能有填充(因此比较器可能会说“不等于”,而实际上它们是相等的)。
但您只想与“默认”(归零)值进行比较,作为奖励,您的记录类型恰好是 packed,因此您可以侥幸逃脱
type
TDummy = packed record
Text: string;
Number: Integer;
end;
TZeroRecord<T: record> = record
class function IsZero([Ref] const ARecord: T): Boolean; static;
end;
{ TZeroRecord<T> }
class function TZeroRecord<T>.IsZero([Ref] const ARecord: T): Boolean;
begin
var DefT := Default(T);
Result := CompareMem(@ARecord, @DefT, SizeOf(T));
end;
和
procedure TForm1.FormCreate(Sender: TObject);
var
D: TDummy;
begin
D := Default(TDummy);
if TZeroRecord<TDummy>.IsZero(D) then
ShowMessage('D is empty.');
D.Number := 394;
if TZeroRecord<TDummy>.IsZero(D) then
ShowMessage('D is empty.');
end;
但这太疯狂了。