Rob, Having lost many hours over the years over this very error; I have to speak up. And having lurked for many months, I've watched your posts for a long time now and know that you really know your stuff. But I disagree with you here.
The "as" operator will raise an runtime exception if the object can't be cast. You get no warning of any kind. How could it be otherwise? Thinking that maybe I was overlooking something, I just tested this by creating two classes, instantiating one and trying to cast it to the other using the "as" operator without first testing it. I was using Delphi 2005. The build went without warnings or hints. I got a runtime exception "Invalid cast Typecast". I agree that in the contrived example, the argument should be such that the wrong object can't be passed. But there are a few cases where you really do want to do a cast. It is better to test and prevent an exception then to code with the assumption that everyone will forever obey the rules. Explicit cast TMyObject(obj) assumes that no one will every assign something to obj that isn't a TMyObject. When that assumption is wrong it can take several minutes to figure out why. Delphi has NEVER been good at helping identify this error. More often than not it will take you hundreds of lines of code away from the error once it has recovered from the exception (in the absence of try except code). If you do the test before the cast and if the test fails you assert, the guy who broke your assumption will know immediately what he did wrong because the Assert's message will tell him so. The problem gets corrected before deployment and in seconds or minutes. I have been coding Delphi a long time and have seen this type of error more times than I can count. Especially from C and C++ programmers. Explicit or untested casts don't make sense since the language gives us an easy way to not lay such landmines. I never let this one get by in code reviews. It is just too dangerous. A last note, using interfaces can also provide an alternative to doing a bunch of such casts thereby improving coupling and reducing dependencies. GetInterface basically does this very thing, test then use... Rob, what am I missing here? With respect... Tom ----- Original Message ---- From: Rob Kennedy <[EMAIL PROTECTED]> To: Borland's Delphi Discussion List <[email protected]> Sent: Friday, January 26, 2007 9:36:19 AM Subject: Re: Re[2]: Scope and Message Passing Tom Blocker wrote: > A better way... > type > TMyForm = class(TForm) > public > Test: integer; > end; > > procedure Foo(F: TForm) > begin > if (F is TMyForm) then > (F as TMyForm).Test := 0; > end; That's equivalent to this: if F is TMyForm then if F is TMyForm then TMyForm(F).Test := 0 else raise EConvertError.Create(...); You never need to use "is" and "as" as the same time. The "as" operator performs an "is" test anyway. > Adding an else stmt Assert(False) can do a future programmer a big favor > too. You could also just do this: Assert(F is TMyForm); Then you could continue with the unchecked cast. But, if the function is _always_ supposed to take a TMyForm, then it should be declared to take a TMyForm. Then the compiler will complain when you try to pass anything else. You get the error fixed at compile time instead of having to wait until run time. Another benefit is that there is no type-casting involved anymore, so there is no longer any argument about which kind of type-cast to use. -- Rob _______________________________________________ Delphi mailing list -> [email protected] http://www.elists.org/mailman/listinfo/delphi ____________________________________________________________________________________ Finding fabulous fares is fun. Let Yahoo! FareChase search your favorite travel sites to find flight and hotel bargains. http://farechase.yahoo.com/promo-generic-14795097 _______________________________________________ Delphi mailing list -> [email protected] http://www.elists.org/mailman/listinfo/delphi

