There are a lot of articles about the use and abuse of FreeAndNil but there is one point I really don’t like about FreeAndNil: It is not type-safe. Let’s have a look at the implementation:
{ FreeAndNil frees the given TObject instance and sets the variable reference to nil. Be careful to only pass TObjects to this routine. } procedure FreeAndNil(var Obj); inline; ... procedure FreeAndNil(var Obj); {$IF not Defined(AUTOREFCOUNT)} var Temp: TObject; begin Temp := TObject(Obj); Pointer(Obj) := nil; Temp.Free; end; {$ELSE} begin TObject(Obj) := nil; end; {$ENDIF}
The comment describes the issue: “Be careful to only pass TObjects to this routine.” That’s why I would implement it in a different way:
type TObjectHelper = class helper for TObject public class procedure FreeAndNil<T: class>(var AValue: T); inline; static; end; { TObjectHelper } class procedure TObjectHelper.FreeAndNil<T>(var AValue: T); {$IF not Defined(AUTOREFCOUNT)} var lTemp: TObject; begin lTemp := AValue; AValue := nil; lTemp.Free; end; {$ELSE} begin AValue := nil; end; {$ENDIF}
This code is type-safe and don’t use pointer arithmetic. Maybe I will ask Marco if there is a chance to add the generic FreeAndNil method directly to TObject.