tags:

views:

3438

answers:

4

Hi,

When I am trying to cast Object obj to Type T, If it can not be cast then there is something wrong.

And after I cast the object I will be looking for working with the casted object.

Rather I will be expecting to get an exception at the place where I will be casting it than say where I will be using that object.

In this sense is it better to use DirectCast instead of TryCast ?

Or Am I missing some other significance of using TryCast ?

Thanks.

+15  A: 

(For C# developers, TryCast is similar to "as" and DirectCast is the equivalent of normal casting. As Mike pointed out in the comments, "as" works for nullable value types, but TryCast doesn't.)

If the value really should be a T, then DirectCast is indeed the right way to go - it fails fast, with an appropriate error.

TryCast is appropriate when it's legitimate for the target to be the "wrong" type. For instance, to get all the Button controls in a container, you could go through the control collection and try to cast each to Button. If it works, you do something with it - if it doesn't, you move on. (With LINQ you can just use OfType for this purpose, but you see what I mean...)

In my experience direct casting is appropriate more often than TryCast - although with generics I find myself casting a lot less often than I used to anyway.

Jon Skeet
However, TryCast is not identical to C#'s "as". TryCast only works with reference types, whereas "as" handles value types. See my question on this issue (http://stackoverflow.com/questions/1297297/differences-between-vb-trycast-and-c-as-operator-when-using-linq)
Mike Thompson
@Mike: Your comment makes it sound like "as" handles *all* value types. It only handles *nullable* value types. But yes, this is a difference. Will edit.
Jon Skeet
+6  A: 

The only difference between the two is that, a TryCast will return a null if it fails, while a DirectCast will throw an exception.

These has implications on how you can handle your program. Personally I prefer not having to throw an exception if the possibility of an improper cast (e.g., text input boxes for user input being casted into numeric types) is pretty high.

Jon Limjap
+1  A: 

If your design mandates that the object passed to you MUST be of type T, then assert (as in Debug.Assert) that the cast succeeds in debug builds and run exhaustive unit tests to prove that your implementation follows your design.

With your design proven and tested, you can perfrom the direct cast knowing that it can never fail.

Daniel Paull
+2  A: 

I think the others have mentioned the times when you should and shouldn't perform "safe casting" (where you ensure that the cast can succeed before risking an exception). If your program does need to perform safe casting then the TryCast method saves both you and the program some work.

I wasn't aware of the TryCast() function until today, and I feel like a fool for using the 'bad' method of safely casting.

If you did not know about the TryCast() function then you might end up with something like this:

'' wasteful, the TypeOf and DirectCast calls are redundant
If TypeOf obj Is SomeClass Then
    someObj = DirectCast(obj, SomeClass)
    '' More code
End If

The problem is that this method actually performs two casts (technically I think they're actually type-checks). Using the TryCast and checking if the result is Nothing eliminates the 2nd cast and saves needless work.

'' efficient, only one cast is ever performed and there are no InvalidCastExceptions thrown
someObj = TryCast(obj, SomeClass)
If someObj IsNot Nothing Then
    '' More code
End If

Following this pattern lets you avoid having to handle expensive exceptions, and efficiently cast to the correct type.

STW
...I provided the same advice to a couple contractors working for us and found them abusing TryCast(). Reminder: only use TryCast if there is a VALID reason to expect the object to not be of the target Type. If someObject is always SomeType then DirectCast the sucker and let DirectCast throw an exception if it isn't.The TryCast() abuse left us with bugs with no evidence. The object wasnt the required type, TryCast didn't raise an error, code didn't execute, and no exception was logged.
STW