我无法计算我错误地完成了多少次这样做:
for i := 0 to MyList.count-1 do begin
myobject := TMyObject(MyList[i])
.......
end;
应该是这样的:
for i := 0 to MyList.count-1 do begin
myobject := TMyObject(MyList.objects[i])
.......
end;
请注意第二段代码中的对象。
错误的代码片段将会运行,当我尝试使用myobject时,显然会抛出访问冲突。但是,我做错了并不总是很明显。
是否有编译器选项可以防范这种情况?
答案 0 :(得分:7)
Delphi有两种方法可以使用TObject(var)
进行类型转换,使用As
运算符进行软编。
除非您100%确定,否则始终使用As
运算符是一种很好的做法。
在您的具体示例中
(MyList[i]) as TMyObject
无法编译
在哪里
(MyList.objects[i]) as TMyObject
。
答案 1 :(得分:5)
没有。编译器会假设您在键入时表明您知道自己在做什么。它允许几乎任何类型转换,其中两种类型的大小相同,除了在整数和浮点类型之间进行转换之外。
对于这个特定的例子,尝试让自己养成使用as
运算符的习惯。然后编译器会在您忘记使用Objects
属性时抓住您:
myobject := MyList[i] as TMyObject; // compiler error
myobject := MyList.Objects[i] as TMyObject; // OK
答案 2 :(得分:3)
看起来您正在使用TStringList来保存字符串/对象对。如果您使用的是Delphi 2009或更高版本,则另一个建议是将TStringList替换为通用的TDictionary,如下所示:
uses
Generics.Collections;
...
MyDictionary: TDictionary<String, TMyObject>;
...
for MyObject in MyDictionary.Values do
begin
...
end;
然后整个操作都是类型安全的,你根本不需要进行投射。
注意:您无法在for..in循环中重新分配迭代变量(但您可以调用其方法并更改其属性的值。