I can't count how many times I may have erroneously done this:
for i := 0 to MyList.count-1 do begin
myobject := TMyObject(MyList[i])
.......
end;
when it should be this:
for i := 0 to MyList.count-1 do begin
myobject := TMyObject(MyList.objects[i])
.......
end;
Note the objects in the second snippet of code.
The erroneous snippet of code will run, and will obviously throw an access violation when I try to make use of myobject. But it isn't always apparent what it is I am doing w开发者_如何学Crong.
Is there a compiler option which will guard against this?
Delphi has 2 ways to typecast, hardcast using TObject(var)
and a softcast using the As
operator.
It is a good practice to always use the As
operator unless you are 100% sure.
In your specific example
(MyList[i]) as TMyObject
does not compile
where as
(MyList.objects[i]) as TMyObject
does.
No. The compiler assumes when you type-cast that you know what you're doing. It will allow pretty much any type-cast where the two types are the same size, with the notable exception of casting between integral and floating-point types.
For this particular instance, try getting yourself into the habit of using the as
operator instead. Then the compiler will catch you when you forget to use the Objects
property:
myobject := MyList[i] as TMyObject; // compiler error
myobject := MyList.Objects[i] as TMyObject; // OK
It looks like you are using a TStringList to hold a string/object pair. If you are using Delphi 2009 or later an alternative suggestion is to replace your TStringList with a generic TDictionary like so:
uses
Generics.Collections;
...
MyDictionary: TDictionary<String, TMyObject>;
...
for MyObject in MyDictionary.Values do
begin
...
end;
Then the entire operation is type safe and you won't need to cast at all.
Note: You can't reassign the iteration variable inside a for..in loop (but you can call its methods and change the value of its properties.
精彩评论