Navigation |
>> Home |
Safe Conversion of Reference Types
Written by: Christoph Wille A topic that time and again turns out to be problematic for beginners is the conversion ("casting") of reference types (aka objects). Under C++ quite a lot of havoc could be wreaked with this which fortunately cannot happen with C#. In spite of - or precisely because of - the type safety of the language, one should get acquainted with the various techniques:
To present the topic vividly, I choose a nice scenario: we will try to turn apples into oranges - soemthing C# will not allow (and which therefore is well suited to demonstrate how to handle conversion errors). The basic source code for all examples is the following (classes.aspx): <script language=c# runat=server> class apple { public string Fruit() { return "Apple"; } } class orange { public string Fruit() { return "Orange"; } } </script> <% @page language=c# %> <% apple myApple = new apple(); orange myOrange = new orange(); Response.Write(myApple.Fruit()+"<br>"); Response.Write(myOrange.Fruit()+"<br>"); %> CastingEven though we will fail, we will first try to go 'head through wall': apple myApple = new apple(); orange anotherOrange = (orange)myApple; With this code the compiler will complain: he knows that this conversion is invalid and won't even compile the code. The reason is obvious as the apple class has nothing in common with the orange class. Therefore we will choose another approach which is often taken in real life - first we stick a type in a general object variable (e.g. when saving elements in Stacks, Queues or ArrayLists) and later we convert it back to the (purportedly) right type for reuse: apple myApple = new apple(); // the following line stands for potentially more complicated operations object objGeneral = myApple; orange anotherOrange = (orange)objGeneral; When choosing the wrong type - as we did here, C# will slap our wrists - namely by means of an InvalidCastException at runtime. To properly catch this error, exception handling code is needed, e.g.: apple myApple = new apple(); object objGeneral = myApple; try { orange anotherOrange = (orange)objGeneral; // do whatever you want with the orange } catch(InvalidCastException e) { // either do nothing or tell the user } Even though all errors are now handled, I only find out about a failure of the cast through an exception. It would be much nicer and more convenient, should we be able to ask beforehand whether a cast might succeed or not. This is where the is operator comes into play. The is OperatorAs already announced, the is operator allows to ask whether a cast will succeed or raise an exception. The following sourcecode snippet shows how the is operator can be used in an application: apple myApple = new apple(); object objGeneral = myApple; if (objGeneral is orange) { orange anotherOrange = (orange)objGeneral; // do whatever you want with the orange } else { Response.Write("this is no orange"); } I want to give a hint regarding the is operator - if at compile time it can be determined that the cast always will either succeed or fail, the compiler issues a warning - which however we unfortunately won't see in ASP.NET. The as OperatorThe as operator might be called an exception-less cast. The conversion is silently carried out - should the conversion fail, the target variable of the conversion is set to null. All that remains to be done is to check this variable using an if-statement: apple myApple = new apple(); object objGeneral = myApple; orange anotherOrange; anotherOrange = objGeneral as orange; if (null != anotherOrange) { // do whatever you want with the orange } else { Response.Write("this is no orange"); } For the as operator the same holds true as for the is operator - you will receive a warning, should the cast always succeed or fail. E.g. as in this code: apple myApple = new apple; apple anotherApple = myApple as apple; ConclusionMany ways lead to Rome, some are more tortuos than others however. My personal favourite for type conversions is the is Operator. Downloading the CodeClick here, to start the download.
©2000-2004 AspHeute.com |