2010-08-16 32 views
0

我不能指望有多少次我可能会错误地做到了这一点:是否有一个编译时间标志,以防止从访问对象StringList的不使用“对象”

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时显然会引发访问冲突。但它并不总是显而易见的是我做错了什么。

是否有一个编译器选项可以防止这种情况发生?

回答

7

Delphi有2种方式进行类型转换,hardcast使用TObject(var)和使用As运营商softcast。 除非您100%确定,否则始终使用As运算符是一种很好的做法。 在你的具体例子

(MyList[i]) as TMyObject不编译 其中作为

(MyList.objects[i]) as TMyObject一样。

+0

谢谢。是的 - 我必须开始养成这种习惯。 – 2010-08-16 17:36:57

5

不会。编译器会假设您何时键入 - 您知道自己在做什么。它几乎允许任何类型转换,其中两种类型的大小相同,除了在整型和浮点型之间进行转换之外。

对于此特定实例,请尝试让自己养成使用as运算符的习惯。编译器会抓住你,当你忘记使用Objects属性:

myobject := MyList[i] as TMyObject; // compiler error 
myobject := MyList.Objects[i] as TMyObject; // OK 
+0

他3分钟打你 – 2010-08-16 17:36:34

+2

@ M Schenkel - 你有错误的方法分钟。) – 2010-08-16 17:56:04

3

它看起来像你正在使用TStringList来保存一个字符串/对象。如果您使用的Delphi 2009或更高版本的替代建议是与通用TDictionary更换您的TStringList像这样:

uses 
    Generics.Collections; 
... 
MyDictionary: TDictionary<String, TMyObject>; 
... 
for MyObject in MyDictionary.Values do 
begin 
    ... 
end; 

然后整个操作是类型安全的,你不需要在所有投。

注意:你不能重新分配的for..in循环中的迭代变量(但你可以调用它的方法,并改变其属性值

+2

+1。 TStringList被频繁地用作瑞士军队对象。只要OP实际上想要一个字符串/对象关联列表,而不是恰好附有对象的字符串列表,这可能是比接受的更好的答案。 – 2010-08-16 18:29:07