1

How can I determine whether a Delphi < T > is of a specific class and not for example record? I want to release an element of a list, if it is a class when cleaning.

procedure TTableData<T>.Delete(Index: Integer);
begin
  if Items[Index] is TClass then TClass(Items[Index]).Free;
  inherited Delete(Index);
end;
HemulGM
  • 58
  • 1
  • 5

1 Answers1

2

You can use RTTI, perhaps like this:

uses
  System.TypInfo;

....

procedure TTableData<T>.Delete(Index: Integer);
var
  item: T;
begin
  if PTypeInfo(TypeInfo(T)).Kind = tkClass then
  begin
    item := Items[index];
    TObject((@item)^).Free;
  end;
  inherited Delete(Index);
end;
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • `if Assigned(TObject((@Item)^)) then TObject((@Item)^).Free;` raise Exception if `Item` is already destroyed. And this check does not help. How to check? – HemulGM May 23 '19 at 11:33
  • `First chance exception at $74FBC54F. Exception class EInvalidPointer with message 'Invalid pointer operation'. Process Yotm.exe (7144)` `procedure TObject.FreeInstance; begin CleanupInstance; --> _FreeMem(Pointer(Self)); end;` – HemulGM May 23 '19 at 11:39
  • 3
    See https://stackoverflow.com/a/8550628/505088 You cannot check whether or not an object has already been destroyed. You need to decide on the ownership policy for this container and follow it strictly. You can't mix and match ownership. – David Heffernan May 23 '19 at 11:56
  • 2
    FYI, `PTypeInfo(TypeInfo(T)).Kind` can be replaced with `GetTypeKind(T)` in Delphi XE7+ – Remy Lebeau May 23 '19 at 15:42