Mausimo
Mausimo

Reputation: 8168

Why does the 'as' keyword work while the () cast does not

//always works, returning a valid object into _page
        _page = _httpContext.Handler as System.Web.UI.Page;

//Fails throwing the exception : Unable to cast object of type 'System.Web.DefaultHttpHandler' to type 'System.Web.UI.Page'
        _page = (System.Web.UI.Page)_httpContext.Handler;

I would like to know why this happens?

EDIT:

                //Fixes the problem
            if(_httpContext.Handler is System.Web.UI.Page)
            _page = (System.Web.UI.Page)_httpContext.Handler;

If i debug the 'as' keyword statement, i never get a null reference (object always assigned properly). However the () cast creates exceptions unless it has the if statment.

EDIT: After about 15 runs through the class i was able to get a null. Seems like it took more runs to find a null compared to how fast the () cast would catch an exception.

OLD: When there is a debug at the 'as' statement every time the class runs the break point hits - never null.

When tthere is a debug in the '()' statement within the if, every time the break point hits the cast works properly. Werid

Upvotes: 7

Views: 1543

Answers (9)

kemiller2002
kemiller2002

Reputation: 115538

//always works, returning a valid object into _page _page = _httpContext.Handler as System.Web.UI.Page;

This didn't technically work. If you'll notice _page will be null. It just didn't throw an error.

The as operator is used to tell the application "I want you to try and convert this. It might not, and I know this, so don't throw an exception. I'll deal with it accordingly."

The () conversion is used to tell the application, "This object will cast to this type. If it doesn't something is wrong, and I need to know about it."

The difference between the two casts (and when you should use them) is when you "think" something is castable to another type and when you "know" something is castable to another type.

Here is an article by Eric Lippert on the subject (changed to his blog not re-feeded): http://blogs.msdn.com/ericlippert/archive/2009/10/08/what-s-the-difference-between-as-and-cast-operators.aspx

Upvotes: 14

RationalGeek
RationalGeek

Reputation: 9609

As other answers have noted, it boils down to the fact that "as" will return null in the event of an invalid cast, whereas an explicit cast will throw an exception.

The other answers have some debate over whether to lean toward one or the other. If you are going to use "as", you need to deal at some point with the fact that it may be a null. If you are going to use an explicit cast you have to deal with a possible exception. Depending on the use case I lean toward one or another.

I tend to use the specific cast when I know that the cast will work but the compiler doesn't, and throwing an exception would be okay (because it is an exceptional case). But if there is a legitimate chance that the cast will be invalid, I prefer using "as" and testing for null. This avoids catching the exception which is uglier and makes debugging harder IMO.

Upvotes: 0

Dinah
Dinah

Reputation: 54077

Actually, that's exactly what's supposed to happen. The cast failed and threw and error because the cast wasn't valid. The as quietly defaults to null if the cast fails.

Upvotes: 0

KevenK
KevenK

Reputation: 3021

As many are pointing out, the as operator is returning a null in this case, avoiding the "problem" but not really "working".

This site has a good description of the 3 differences between using as and casting:

http://en.csharp-online.net/CSharp_FAQ:_What_is_the_difference_between_using_a_cast_and_the_as_operator

Upvotes: 0

Andrew Hubbs
Andrew Hubbs

Reputation: 9436

One major difference between the as cast and the prefix cast is that the prefix cast will throw an exception while the as cast will just return null.

Upvotes: 4

Earlz
Earlz

Reputation: 63935

The same thing that @Tejs answer said. A failed conversion with as produces null.

I'm going to say different from him though and as a general rule you should always use an explicit cast. I personally had much rather get an exception right where the conversion fails rather than in another page get a (seemingly) out of nowhere null reference exception.

One good use for the as operator though is when converting things out of a database and not wanting to check for System.DBNull

int someint = cmd.ExecuteScalar() as int? ?? 0;

Upvotes: 0

Mark Carpenter
Mark Carpenter

Reputation: 17775

Using as TRIES to cast that object to that specific type, but returns null on failure instead of throwing an exception (whereas casting just throws the exception). Are you sure the one with the as clause is actually returning a non-null object?

Upvotes: 0

davek
davek

Reputation: 22925

From here:

Using the as operator differs from a cast in C# in three important ways:

It returns null when the variable you are trying to convert is not of the requested type or in it's inheritance chain, instead of throwing an exception. It can only be applied to reference type variables converting to reference types. Using as will not perform user-defined conversions, such as implicit or explicit conversion operators, which casting syntax will do. There are in fact two completely different operations defined in IL that handle these two keywords (the castclass and isinst instructions) - it's not just "syntactic sugar" written by C# to get this different behavior. The as operator appears to be slightly faster in v1.0 and v1.1 of Microsoft's CLR compared to casting (even in cases where there are no invalid casts which would severely lower casting's performance due to exceptions).

Upvotes: 7

Tejs
Tejs

Reputation: 41266

If you use the 'as' operator, if the conversion fails, it just returns null. If you do an explicit cast, it will throw an exception if the conversion fails. In this situation, the 'as' downcasts to the proper type expected. The explicit conversion can't move up to the desired type.

As a general rule, you should always do 'as' unless you really need the explicit cast (such as when you need to convert to value types).

Upvotes: 0

Related Questions