gpt4 book ai didi

arrays - 在将动态数组作为变量参数传递之前是否可以强制转换?

转载 作者:行者123 更新时间:2023-12-03 19:37:09 26 4
gpt4 key购买 nike

我有一些函数可以接受TObject数组作为var参数,例如:

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;


为了重用相同的功能,在将 TObject的后代类的多个动态数组传递给 TObjectArray之前,我将它们转换为函数,例如:

var
Buttons : array of TButton;
begin
SetLength(Buttons, 1);
Buttons[0] := Button1;

//...

DeleteAt(TObjectArray(Buttons), 0);
end;


这是安全的做法,还是可能引起我没有考虑的问题?

最佳答案

只要阵列兼容,该技术本身不会造成伤害。 array of TObject的成员只是对对象的引用。由于可以从祖先引用中安全地使用对象,因此不存在固有问题。

当然,您在问题中显示的代码是安全的。如果就所有权模式而言,您甚至可以Free删除/删除的对象实例。



也就是说,存在编译器无法执行其任何典型类型安全检查的风险。


在极端情况下,您可以在array of Bytearray of TObject之间进行转换
更巧妙地,您可能会意外地在不兼容的对象类型的数组之间进行转换(例如,在array of TButtonarray of TQuery之间进行转换)。使用单个对象时,可以选择使用(<object> as <type>)进行选中的类型转换。这将执行编译时检查,以验证类型是否在同一层次结构中(否则,强制转换是不兼容的),并执行运行时检查以确保对象实例实际上是正确的类型。
尽管删除和交换数组中的对象是安全的,但var引用意味着您还可以将对象添加到数组中。现在,array of TButton会强制您添加TButton(或子类)实例;将类型转换为array of TObject意味着您可以不小心将任何其他对象添加到数组。当函数返回时,代码将尝试非常错误地使用对象。您几乎肯定会遇到奇怪的行为和/或访问冲突。由于根问题已在程序的较早版本中无声引入,因此调试起来将更加困难。




结论

尽管该技术有效,但最好还是建议您使用TObjectList


这保留了基于标准对象的类型检查。
它支持与数组相似的用法,因此通常是一个很好的替代品。
此外,该容器还可以在添加和删除项目时动态调整大小,而无需手动调整大小。
唯一的不便之处是您必须创建和销毁TObjectList


尽管您必须在TList和类类型之间执行未经检查的强制转换,甚至Pointer还是通常更好的选择。

关于arrays - 在将动态数组作为变量参数传递之前是否可以强制转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49382574/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com