A+ A A-

Delphi Managed Records - Making your code smart

With Delphi 10.4, Managed Records language feature was introduced. As some might remember, it was originally intended for Delphi 10.3, but Embarcadero wisely decided to postpone the feature, to ensure a solid implementation - and now we have it!

It is important to mention, this is a language feature available with Delphi 10.4 and newer.

Managed Records opens up many new possibilities to write smarter and more effective code without syntactic sugar and bloat which other popular languages suffer from. This is one of the many reasons I keep using Delphi - the language is simple, yet powerful and allows you to eloquently write software.
Writing software is after all an art, just like writing a novel.

Anyways, back to the actual topic - Managed Records.

In this article, I want to share a little clever tidbit of how you can utilize the automatic initalization and finalisation calls of Managed Records. 
INI files is still one of the easiest ways to have a key-value settings storage across platforms, and usually it takes some legwork to create the object, read or write your settings and ensuring the object is destroyed again.
What if you could access the INI Read or Write features right away and don't worry about keeping track of the object life-cycle?
- Managed Records to the rescue!

In a recent feedback tool I've been working on for another client project, I had the need to save and load a few settings throughout the application.
I figured I didn't want to do the classic create object, do my operation in a try-finally block and close down the object again and thought that Managed Records automatic initialization and finalization should be able to do the trick.
The following snippet illustrates how this can be done:

unit MRTest.AppSettings;



  TAppSettings = record
  strict private const
    cIniFileName: string = 'TestSettings.ini';
  strict private
    FAppConf: TMemIniFile;
    class function TAppSettings.InternalGetFullIniFile: string; static;
    class operator Initialize(out ADest: TAppSettings);
    class operator Finalize(var ADest: TAppSettings);
    property AppConf: TMemIniFile read FAppConf write FAppConf;


{ TAppSettings }

class operator TAppSettings.Initialize(out ADest: TAppSettings);
  ADest.FAppConf := TMemIniFile.Create(ADest.InternalGetFullIniFile);
  ADest.FAppConf.AutoSave := True;

class operator TAppSettings.Finalize(var ADest: TAppSettings);

class function TAppSettings.InternalGetFullIniFile: string;
  Result := TPath.Combine(TPath.GetDocumentsPath, cIniFileName);



Now you can just include the unit in your project where needed and automatically allocate a variable of the type TAppSettings (Or whatever name your record type has).
The example below has been reduced for the simplicity to give you a gist of how it can be approached.


procedure LoadSettings;
  var LApp: TAppSettings;
  CheckBox1.Checked := LApp.AppConf.ReadBool('Settings', 'FirstStart', True);

procedure SaveSettings;
  var LApp: TAppSettings;
  LApp.AppConf.WriteBool('Settings','FirstStart', CheckBox1.Checked);

As you see, everything is encapsulated in the record type and the managed nature automatically takes care of creating the INI object with the correct settings when it goes into scope, and unloads it again once it goes out of scope.

I hope you found this information useful.

We use cookies on our website. Some of them are essential for the operation of the site, while others help us to improve this site and the user experience (tracking cookies). You can decide for yourself whether you want to allow cookies or not. Please note that if you reject them, you may not be able to use all the functionalities of the site.