Delphi:如何将所有 class 字段重置为零值?

Delphi: How can I reset all class fields to zero value?

我有一个 class 有很多数字字段,字段的数量会随着项目的发展而增加,所以如果有一种方法可以重置所有字段,无论将来添加多少.

 TParams = class
  public
    defined:  boolean;
    FirstValue:             byte; // reset from here
    A0:       single; 
    A1:       single; 
    H1:       TPoint;
       // ...............
    A100:     single; 
    LastValue:             byte; // to here
    procedure Reset;
  end;

想到的唯一想法是插入 2 个字段:应该重置的块之前和之后,并使用 FillMemory:

procedure TParams.Reset;
begin
  FillMemory(@FirstValue, Integer(@LastValue)-Integer(@FirstValue),0);
end;

有没有更好的方法? (我正在使用 Delphi 7)

在某些受限制的情况下,例如您使用 TParams 的情况,调用 InitInstance 应该可以解决问题:

procedure TParams.Reset;
begin
  InitInstance(Self);
end;

David Heffernan 已经说过了:你正在做的是一个丑陋的 hack,而且不是很干净。他还给出了提示:把你的数字字段变成一条记录:

type
  TParams = class
  public
    Defined: Boolean;
    Numbers: record
      A0: Single;
      A1: Single;
      H1: TPoint;
      A100: Single;
    end;
    procedure Reset;
  end;

现在就很简单了,你可以Reset通过下面的操作:

procedure TParams.Reset;
begin
  FillChar(Numbers, SizeOf(Numbers), 0);
end;

一个简单的测试:

procedure Test;
var
  P: TParams;
begin
  P := TParams.Create;
  try
    Writeln(Format('%f %f (%d, %d) %f', [P.Numbers.A0, P.Numbers.A1, P.Numbers.H1.X, P.Numbers.H1.Y, P.Numbers.A100]));
    P.Numbers.A0 := 1.0;
    P.Numbers.A1 := 2.0;
    P.Numbers.H1 := Point(11, 22);
    P.Numbers.A100 := 77.0;
    Writeln(Format('%f %f (%d, %d) %f', [P.Numbers.A0, P.Numbers.A1, P.Numbers.H1.X, P.Numbers.H1.Y, P.Numbers.A100]));
    P.Reset;
    Writeln(Format('%f %f (%d, %d) %f', [P.Numbers.A0, P.Numbers.A1, P.Numbers.H1.X, P.Numbers.H1.Y, P.Numbers.A100]));
  finally
    P.Free;
  end;
end;

这会产生以下输出:

0.00 0.00 (0, 0) 0.00
1.00 2.00 (11, 22) 77.00
0.00 0.00 (0, 0) 0.00

或者,您可以执行以下操作:

  TNumbers = record
    A0: Single;
    A1: Single;
    H1: TPoint;
    A100: Single;
  end;

  TParams = class
  public
    Defined: Boolean;
    Numbers: TNumbers;
    procedure Reset;
  end;

对于那些带有泛型的版本(我知道您使用的是 Delphi 7,它没有泛型,但无论如何,对于其他版本),这将简化 Reset 一点:

procedure TParams.Reset;
begin
  Numbers := Default(TNumbers);
end;

Default 的优点是它将正确地完成和初始化记录,以防万一它在其中管理类型(字符串、接口等)。