Ответ 1
Вы можете использовать скрытое строковое поле (которое автоматически инициализируется пустой строкой), чтобы реализовать инициализацию "по времени" и неявные операторы, чтобы скрыть детали реализации. В приведенном ниже коде показано, как реализовать "двойное" поле, которое автоматически инициализируется на 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 и изменить значение по умолчанию.