Wednesday, September 28, 2011

VB.NET Stupidisms - IsNot and AndAlso


Let's take the IsNot operator that will let you write:
If Not lMyVar is Nothingthen ...do something... end if
as
If lMyVar IsNot Nothingthen ...do something... end if
In this particular case there hasn't been any signfiicant performance or recommendation to use either form except that the IsNot operator makes the code more readable (IMHO).  Wikipedia had a funny reference to a patent application that Microsoft had filed on the operator.  While the example code above depicts using a comparison against Nothing the comparison can be done against any reference.
A more important stupidism that I thought worth posting has to do with how Visual Basic implements short-circuiting in boolean comparisons through the use of the AndAlso operator.  This allows for bypassing of future operands in the expression if a prior one determines the outcome of the evaluation.  For example, if all of the operands in an IF/THEN are evaluating to see whether the result is true, if any of hte operands return false, there is no need to continue evaluating the rest.
For example, in the evaluation below, both the first and second operand are evaluated in order to determine the result.  This results in two operatins/comparisons being made even if the first operand returns false (e.g., lValue = 10).
If lValue > 50 and lValue < 100 Then
Using a short-circuited evaluation with the AndAlso operator avoids this as follows:
If lValue > 50 AndAlso lValue < 100 Then
A friend reminded me that Basic has been this way forever and in fact Microsoft introduced the AndAlso operator to address this shortcoming.  He also scolded me for doing too much C++ development as of late.  Wikipedia has a great reference that includes a table (included in this posting) outlining how various languages provide for short-circuited boolean evaluations.
Language Eager operators Short-circuit operators Result type
ABAPnoneand , orBoolean1
Ada, Eiffeland , orand then , or elseBoolean
ALGOL 68and , & , ∧ ; or , ∨andf , orf (both user defined)Boolean
C2none&& , ||, ?[1]Numeric (&&,||), opnd-dependent (?)
C++&, |&& , ||, ?[2]Boolean (&&,||), opnd-dependent (?)
Go, Objective Caml, Haskellnone&& , ||Boolean
C#, Java,
MATLAB,[3] R
& , |&& , ||Boolean
ColdFusionnoneAND , OR , && , ||Boolean
Erlangand, orandalso , orelseBoolean
Fortran.and. , .or.Boolean
JavaScriptnone&& , ||Last value
Lisp, Lua, Schemenoneand , orLast value
Modula-2noneAND , ORBoolean
Oberonnone& , ORBoolean
Pascaland, or3and_then , or_else4Boolean
Perl, Ruby& , |&& , and , || , orLast value
PHPnone&& , and , || , orBoolean
Pythonnoneand , orLast value
Smalltalk& , |and: , or:Boolean
Standard MLUnknownandalso , orelseBoolean
Visual Basic .NETAnd , OrAndAlso , OrElseBoolean
VB Script, VB Classic, VBAAnd , OrSelect CaseNumeric

Thursday, September 1, 2011

VB.NET Stupidisms - DirectCast over CType


I've been diving a bit more into vb.net development recently and decided for my own sanity it might be worthwhile to post some stupid simple notes on what I am learning as I go along.
The first has to do with using DirectCast instead of CType.  The easy answer is that DirectCast performance is marketably better.  The restriction is that you need to ensure you are essentially doing a cast as opposed to a conversion.
The better and longer answer that I'm going to quote directly from can be found in the repsonse to a question posted here.
Here's a quick outline of the differences and recommendations of where you
should ctype and directcast (IHMO anyway)

1) CType is capable of a *cast* or a *conversion*. DirectCast can only
*cast*

By "conversion" I mean converting one datatype to another (e.g. string to
integer, decimal to integer, object to string etc).

By "cast" I mean changing one type of object into another type that is
related to it by one of the following rules:

a) The type you're converting the object to must be the same type
e.g.
--------------
Dim a as String = "hello"
Dim b as Object = a
Dim c as string = directcast(b, String)
--------------

Variable b is an object that holds a string, so you can cast it to a string.
b) If converting to an interface, the type you're converting must implement
the interface
e.g.
---------------------
Dim a as New MyInterfaceObejct
Dim b as IInterface = directcast(a, IInterface)
----------------------

c) If converting to a derived type, the runtime type of the object must be
the derived type or one of it's own derived types :S
e.g.
----------------------
Dim a as Base = New Derived
Dim b as Derived = directcast(a, Derived)
----------------------

2) Use directcast whenever a "type relationship" exists - it is slightly
faster (in some cases anyway), but forces you to be more aware of
conversions that are going on.

3) Use Ctype when a type relationship doesn't exist, but a value
relationship does (e.g. converting the string "123" to the integer 123)











Hopefully this particular description was is as helpful to others as it was for me.