Reputation: 8043
I have some functions which accepts an array of TObject
as a var
parameter, for example:
type
TObjectArray = array of TObject;
...
procedure DeleteAt(var AArray : TObjectArray; AIndex : integer);
begin
while(AIndex < Length(AArray) - 1) do
begin
AArray[AIndex] := AArray[AIndex + 1];
Inc(AIndex);
end;
SetLength(AArray, Length(AArray) - 1);
end;
For reusing the same functions, I'm casting several dynamic array of TObject
's descendant classes to TObjectArray
before passing them to my functions, for example:
var
Buttons : array of TButton;
begin
SetLength(Buttons, 1);
Buttons[0] := Button1;
//...
DeleteAt(TObjectArray(Buttons), 0);
end;
Is this a safe practice or it could cause some problem that I didn't considered?
Upvotes: 1
Views: 264
Reputation: 14832
The technique itself doesn't cause harm provided the arrays are compatible. The members of an array of TObject
are simply references to objects. Since objects can be used safely from an ancestor reference, there is no inherent problem.
Certainly the code you've shown in your question is safe. You could even Free
the object instance you're removing/deleting if that makes sense in terms of your ownership pattern.
That said, there is a risk in that the compiler is unable to perform any of its typical type safety checks.
array of Byte
and array of TObject
array of TButton
and array of TQuery
). When working with individual objects you have the option of a checked type-cast using (<object> as <type>)
. This performs a compile-time check to verify the types are within the same hierarchy (otherwise cast is guaranteed to be incompatible), and a run-time check to ensure the object instance is actually of the correct type.var
reference means you can also add objects to the array. Now whereas an array of TButton
forces you to add TButton
(or subclass) instances; having typecast to array of TObject
means you can accidentally add any other object to the array. And when the function returns, code will attempt use objects very incorrectly. You're almost certain to get strange behaviour and/or access violations. They will be much more difficult to debug due to the root problem having been silently introduced earlier in the program.While the technique works, you'd be much better advised to use a TObjectList
.
TObjectList
.Even TList
would be a generally better choice, though you'd have to perform unchecked casting between Pointer
and class types.
Upvotes: 3