要初始化Delphi记录,我总是添加一个初始化为已知良好默认值的方法(类或对象)。 Delphi还允许使用参数定义记录“构造函数”,但是您无法定义自己的无参数“构造函数”。
TSomeRecord = record
Value1: double;
Value2: double;
procedure Init;
end;
procedure TSomeRecord.Init;
begin
Value1 := MaxDouble;
Value2 := Pi;
end;
鉴于上述记录,没有警告说记录尚未初始化。开发人员可能会忽略在记录上调用Init
。有没有办法自动将记录初始化为我的默认值,可能不仅仅是一个简单的FillChar
;
例如
var
LSomeRecord: TSomeRecord
begin
// someone forgot to call LSomeRecord.Init here
FunctionThatTakesDefaultSomeRecord(LSomeRecord);
end;
如何将记录自动初始化为我的默认值?
[注] 我不想在答案后修改问题。任何读者都可以阅读关于使用类方法进行初始化而不是变异对象方法的最佳实践的注释。
答案 0 :(得分:4)
您可以使用隐藏的字符串字段(自动初始化为空字符串)来实现“按时”初始化,隐式操作符可以隐藏实现细节。下面的代码显示了如何实现一个自动初始化为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定义/实现并更改默认值。
答案 1 :(得分:2)
AFAIK你不能诉诸于不值得的技巧(可能使用保证初始化的界面字段)。
答案 2 :(得分:0)
这将是一个不错的功能...但是我想您可以使用某种工厂?或只是一种卑鄙的方法来返回记录...