Recordisempty?

Is there any data in a Record Type with Delphi? How is it understood?

For example, supposedly get a Record Type like this;

type
  TDummy = PACKED record
    Text   : String;
    Number : Integer;
  end;
var
  aRecord : TDummy;
begin
  aRecord := default(TDummy);   // In this state "aRecord" is empty. (Text = '' and Number = 0)
  aRecord.Text := 'TEST';       // This is no longer empty
end;

So is there any way to figure out this without browsing through the Record Items?

回答

Using a member function

By far the cleanest approach, IMHO, is to declare a method 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;

Then you can always use this method to see if the record is empty:

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;

Using the equals operator

A different approach:

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;

Now you can do

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;

Crazy stuff

If you absolutely do not want to compare each member separately, you can under some circumstances compare the bytes.

但请注意,一般情况下,不能通过比较字节来比较两条记录。只提两个明显的原因:

  1. 字符串成员在语义上可能是相等的,即使它们由两个不同的字符串堆对象表示(因此比较器说“不相等”而实际上它们是相等的)。

  2. 如果记录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;

但这相当疯狂。


以上是Recordisempty?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>