Читая Delphi Memory Management, открыл для себя SmartPointers. Подход, основанный на ARC, позволяет, применяя данный класс писать меньше кода, заниматься больше делом, сосредоточиться на бизнес-задаче.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
unit uSmartPointer; interface type ISmartPointer<T> = reference to function: T; TSmartPointer<T: class, constructor> = class(TInterfacedObject, ISmartPointer<T>) private FValue: T; function Invoke: T; procedure SetValue(const Value: T); public constructor Create; overload; constructor Create(AValue: T); overload; destructor Destroy; override; function Extract: T; property Value: T read FValue write SetValue; end; implementation constructor TSmartPointer<T>.Create; begin inherited Create; FValue := T.Create; end; constructor TSmartPointer<T>.Create(AValue: T); begin inherited Create; FValue := AValue; end; destructor TSmartPointer<T>.Destroy; begin FValue.Free; inherited; end; function TSmartPointer<T>.Invoke: T; begin Result := FValue; end; procedure TSmartPointer<T>.SetValue(const Value: T); begin FValue := Value; end; function TSmartPointer<T>.Extract: T; begin Result := FValue; FValue := nil; end; end. |
Теперь можно писать так…
1 2 3 4 5 6 |
var sl: ISmartPointer<TStringList>; begin sl := TSmartPointer<TStringList>.Create(); sl.Add('I am inside automanaged StringList'); end; |
Вместо…
1 2 3 4 5 6 7 8 9 10 |
var sl: TStringList; begin sl := TStringList.Create; try sl.Add('I am inside regular StringList'); finally sl.Free; end; end; |
Все хорошо, но при отладке не видит значений в TStringList, может и это можно обойти. В целом, подход хорош, меньше кода, больше дела)