Suppose I have a control within a webforms GridViewRow...
<asp:Literal ID="ltl_abc" runat="server" />
Within the RowDataBound event I can access the control using any of the following methods. I've always used DirectCast historically:
Protected Sub gv_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles gv.RowDataBound
Select Case e.Row.RowType
Case DataControlRowType.DataRow
' 1) Dim ltl_abc As Literal = DirectCast(e.Row.FindControl("ltl_abc"), Literal)
' 2) Dim ltl_abc As Literal = CType(e.Row.FindControl("ltl_abc"), Literal)
' 3) Dim ltl_abc As Literal = e.Row.FindControl("ltl_abc")
Is there any advantage of using any particular approach? I guess DirectCast is slightly more efficient, but possibly prone to errors, but are there any dangers of the implicit cast (option 3)?
Historically I've never seen any errors until I try to actually assign a value to the control's property, which makes me think that this first step isn't really that important?
Please note this is not meant to be a DirectCast vs CType discussion, more about whether casting is even necessary here?
Update for clarity
Protected Sub gv_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles gv.RowDataBound
Select Case e.Row.RowType
Case DataControlRowType.DataRow
' This works fine, but no explicit casting is done:
Dim ltl_abc As Literal = e.Row.FindControl("ltl_abc") ' no (explicit) cast
ltl_abc.Text = "Hello World"
' This also works until I try to access the object's properties
Dim ltl_abc As Literal = DirectCast(e.Row.FindControl("NonExistentId"), Literal)
Why therefore should a developer cast (in this example), or is this example just too simple?
For your situation,
TryCast
with anIsNot Nothing
check might be more beneficial.To understand when and why to use which, though, first take a look at the MSDN definitions of them.
DirectCast
CType
Implicit Conversion
TryCast
Going off of those definitions, we can assume that
CType
will make an external call based on a givenSystem.Type
, whileDirectCast
will just use the existing object under a different moniker. Meanwhile, with implicit conversion, VB will just try to execute the code.TryCast
, however, will try to cast the object or just returnNothing
(think of the C#as
operator)For example:
The first example works, because
obj
is already aString
that has just been defined as anObject
. No actual conversion is taking place.Now let's look at
CType
:And finally, implicit conversion:
Both of these work, but remember that VB.NET is calling a separate library here to do the dirty work:
DirectCast:
CType/Implicit Conversion (compiles the same):
So, basically, due to .NET needing to call external methods to determine what it needs to do to convert the object,
CType
/implicit will run somewhat slower (example benchmarks and examples here). Note, since they both compile the same in MSIL,CType
and implicit conversion should perform identically.So when do you use them? I generally follow a couple simple rules
DirectCast
Dim myInt = CInt("42")
. Note, this compiles the same way asCType
in the ILTryCast
DirectCast
and/orConvert.ChangeType
, depending on the contextYou could also use
CType
for the second one there, but in my opinion, if I know I'm converting to anInteger
, then I'll choose the more explicitCInt
. If you haveOption Strict
on, though, you should get a build error either way if you pass the wrong thing into either.Also, while you might tempted to try substituting
TryCast
forDirectCast
check the answer to this SO question regarding major differences and uses: Why use TryCast instead of Directcast?If you notice, I did not include implicit typing in there. Why? Well, mostly because I code with
Option Strict On
, and it doesn't really allow implicit conversions when narrowing types (see "Widening and Narrowing Conversions"). Otherwise, as far as the .NET is concerned, it's pretty much identical toCType
Ok, now that all of that's done, let's look at all three (four, I guess) with
Control
objects:And one more:
So, for your situation, it looks like
TryCast
with aIsNot Nothing
check is the way to go.