是否有编译时标志来防止从StringList访问对象而不使用“对象”

时间:2010-08-16 16:27:40

标签: delphi

我无法计算我错误地完成了多少次这样做:

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时,显然会抛出访问冲突。但是,我做错了并不总是很明显。

是否有编译器选项可以防范这种情况?

3 个答案:

答案 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循环中重新分配迭代变量(但您可以调用其方法并更改其属性的值。