如何自动初始化Delphi记录? [英] How can Delphi records be initialized automatically?

查看:77
本文介绍了如何自动初始化Delphi记录?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

要初始化Delphi记录,我总是添加了一个方法(类或对象),该方法将初始化为已知的默认值.Delphi还允许使用参数定义记录构造函数",但是您不能定义自己的无参数构造函数".

To initialize Delphi records I've always added a method (class or object) that would initialize to known good defaults. Delphi also allows for defining record "constructors" with parameters, but you cannot define your own parameter-less "constructor".

TSomeRecord = record
 Value1: double;
 Value2: double;

 procedure Init;
end;

procedure TSomeRecord.Init;
begin
  Value1 := MaxDouble;
  Value2 := Pi;
end; 

鉴于上面的记录,没有警告未初始化记录.开发人员可能会忽略调用记录上的 Init .有没有一种方法可以自动将记录初始化为我的默认设置,可能不仅仅是简单的 FillChar ;

Given the record above there is no warning that a record has not been initialized. Developers may neglect to call Init on the record. Is there a way to automatically initialize records to my default, potentially more than just a simple FillChar;

例如

var 
  LSomeRecord: TSomeRecord
begin
  // someone forgot to call LSomeRecord.Init here
  FunctionThatTakesDefaultSomeRecord(LSomeRecord);
end; 

如何将记录自动初始化为默认值?

How can a record be initialized to my defaults automatically?

[注意]回答问题后,我不想修改问题.指导所有读者阅读有关使用类方法进行初始化而不是使用变异对象方法的最佳实践的注释.

[Note] I don't want to modify the problem after it has been answered. Any readers are directed to read the comments on best practices on using class methods for initialization instead of a mutating object method.

推荐答案

您可以使用隐藏的字符串字段(会自动将其初始化为空字符串)来实现按时"初始化,并使用隐式运算符来隐藏实现细节.下面的代码显示了如何实现自动初始化为Pi的'double'字段.

You can use a hidden string field (which is automatically initialized to an empty string) to implement 'on time' initialization and implicit operators to hide implementation details. The code below shows how to implement a 'double' field which is automatically initialized to Pi.

program Project44;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

type
  TAutoDouble = record
  private
    FValue: double;
    FInitialized: string;
    procedure Initialize(const val: double = Pi);
  public
    class operator Implicit(const rec: TAutoDouble): double;
    class operator Implicit(const val: double): TAutoDouble;
  end;

  TSomeRecord = record
    Value1: TAutoDouble;
    Value2: TAutoDouble;
  end;

{ TAutoDouble }

procedure TAutoDouble.Initialize(const val: double);
begin
  if FInitialized = '' then begin
    FInitialized := '1';
    FValue := val;
  end;
end;

class operator TAutoDouble.Implicit(const rec: TAutoDouble): double;
begin
  rec.Initialize;
  Result := rec.FValue;
end;

class operator TAutoDouble.Implicit(const val: double): TAutoDouble;
begin
  Result.Initialize(val);
end;

var
  sr, sr1: TSomeRecord;

begin
  try
    Writeln(double(sr.Value1));
    Writeln(double(sr.Value2));
    sr.Value1 := 42;
    Writeln(double(sr.Value1));
    sr1 := sr;
    Writeln(double(sr.Value1));
    Writeln(double(sr.Value2));
    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

但是,没有什么好方法可以使此解决方案的默认值更通用-如果您需要其他默认值,则必须克隆TAutoDouble定义/实现并更改默认值.

There's, however, no nice way to make this solution more generic regarding the default value -- if you need a different default value you have to clone TAutoDouble definition/implementation and change the default value.

这篇关于如何自动初始化Delphi记录?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆