0

So, once again I am learning new things and I came across Smart Pointers. I had code

procedure TForm3.BitBtn1Click(Sender: TObject);
var
  _StringList: ISmartPointer<TStringList>;
begin
  _StringList := TSmartPointer<TStringList>.Create(TStringList.Create);
end;

As you see variable declaration is kinda odd, and simplification is needed. I came across another solution

procedure TForm3.btnDelphiClick(Sender: TObject);
var
  _StringList: TStringList;
begin
  _StringList := SmartGuard.SmartGuard<TStringList>(TStringList.Create(False));
end;

Sadly, it does not work with parameterless constructor

procedure TForm3.btnDelphiClick(Sender: TObject);
var
  _StringList: TStringList;
begin
  _StringList := SmartGuard.SmartGuard<TStringList>(TStringList.Create);
end;

[dcc32 Error] Main.pas(47): E2089 Invalid typecast

Am I out of luck here? P.S. I know some of you would argue I should stick to try..finally block, but this is out of curiosity.

unit SmartGuard;

interface

type
  IGuard = interface
  ['{CE522D5D-41DE-4C6F-BC84-912C2AEF66B3}']
  end;

  TGuard = class(TInterfacedObject, IGuard)
  private
    FObject: TObject;
  public
    constructor Create(AObject: TObject);
    destructor Destroy; override;
  end;

  SmartGuard<T: class> = record
  private
    FGuard: IGuard;
    FGuardedObject: T;
  public
    class operator Implicit(GuardedObject: T): SmartGuard<T>;
    class operator Implicit(Guard: SmartGuard<T>): T;
  end;

implementation

uses
  {Delphi}
  System.SysUtils
  {Project}
  ;

constructor TGuard.Create(AObject: TObject);
begin
  FObject := AObject;
end;

destructor TGuard.Destroy;
begin
  FObject.Free;
  inherited;
end;

{ SmartGuard }

class operator SmartGuard<T>.Implicit(GuardedObject: T): SmartGuard<T>;
begin
  Result.FGuard := TGuard.Create(GuardedObject);
  Result.FGuardedObject := GuardedObject;
end;

class operator SmartGuard<T>.Implicit(Guard: SmartGuard<T>): T;
begin
  Result := Guard.FGuardedObject;
end;

end.

I would love to find a solution that would not require additional "method" calling as in here https://github.com/marcocantu/DelphiSessions/blob/master/DelphiLanguageCodeRage2018/02_SmartPointers/SmartPointerClass.pas e.g. _StringList.Value.Add('foo'); and "special" brackets e.g. _StringList := TSmartPointer<TStringList>.Create(TStringList.Create)();

1 Answer 1

1

The compiler needs help disambiguating

TStringList.Create

The compiler doesn't know whether this is a reference to a method, or a call to the method.

Disambiguate by adding parens to indicate that it is a call.

_StringList := SmartGuard.SmartGuard<TStringList>(TStringList.Create());
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.