Для полной поддержки того, что вы ищете, потребуется поддержка двух вещей:
- Сборщик мусора. Это единственное, что дает вам свободу ИСПОЛЬЗОВАТЬ что-то, не беспокоясь об освобождении этого. Я бы приветствовал изменение в Delphi, которое дало нам даже частичную поддержку для этого.
- Возможность определения локальных инициализированных переменных. Опять же, я бы очень хотел увидеть что-то подобное.
Между тем, самое близкое, что вы можете получить, это использовать интерфейсы вместо сборки мусора (поскольку интерфейсы подсчитываются по ссылкам, как только они выходят из области видимости, они будут освобождены). Что касается инициализированных локальных переменных, вы можете использовать трюк, аналогичный описанному здесь: Объявление переменных уровня блока для ветвей в delphi
И ради интереса, вот консольное приложение, которое демонстрирует использование «поддельных» локальных переменных, и интерфейсы для получения временных списков, которые легко инициализируются, будут автоматически освобождены:
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils, Generics.Collections;
type
ITemporaryLocalVar<T:constructor> = interface
function GetL:T;
property L:T read GetL;
end;
TTemporaryLocalVar<T:constructor> = class(TInterfacedObject, ITemporaryLocalVar<T>)
public
FL: T;
constructor Create;
destructor Destroy;override;
function GetL:T;
end;
TTempUse = class
public
class function L<T:constructor>: ITemporaryLocalVar<T>;
end;
{ TTemporaryLocalVar<T> }
constructor TTemporaryLocalVar<T>.Create;
begin
FL := T.Create;
end;
destructor TTemporaryLocalVar<T>.Destroy;
begin
TObject(FL).Free;
inherited;
end;
function TTemporaryLocalVar<T>.GetL: T;
begin
Result := FL;
end;
{ TTempUse }
class function TTempUse.L<T>: ITemporaryLocalVar<T>;
begin
Result := TTemporaryLocalVar<T>.Create;
end;
var i:Integer;
begin
try
with TTempUse.L<TList<Integer>> do
begin
L.Add(1);
L.Add(2);
L.Add(3);
for i in L do
WriteLn(i);
end;
ReadLn;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.