Home
  Latest posts
  My Writings
  My Code
  My Gallery
  About me
 
  rssfeed Syndication
 
Bloggtoppen.se
 
 
Links
  Cornerstone
  SweNug
 
Post categories
  misc (48)
  Architecture (21)
  C# (19)
  Asp.Net (2)
  Vb.Net (2)
  Training (7)
  Data (19)
  Events (40)
  Platform (2)
  Orcas (4)
  Updates (3)
  Methods (10)
  Tools (6)
  Announcements (14)
  Languages (1)
  Patterns (6)
  Opinions (11)
  Fun (3)
  Ineta (1)
  Opinion (0)
  Practices (2)
  WCF (5)
 
 
 

Why VB.NET suxx0r

Friday, April 14, 2006
WARNING! This blog post is written in anger and frustration !WARNING

I'm currently recovering from a near VB.NET experience. In a Swedish forum somebody asked about casts from DbNull to concrete types and I decided to swiftly put together an example function that could be reused. The swiftly part was quickly omitted in the so called RAD environment of VB.NET. Here is the story about why.

The function I was about to write was a simple check to see if the input parameter value of the type object was in the concrete form of DbNull. If it was, I would return 0 else it would use the Convert.ToInt64 function to return a Long (Yes I know that Int64.TryParse probably would've solved this quickly but I didn't go down that path for this example).

Since I've used VB and VB.NET some before I know about the IS operator and I know about the IIF function built into the language. So my first attempt looked something like this:

Return IIF ( value Is DbNull, 0, Convert.ToInt64(value)  )

Standard C# code converted into VB.NET. Now that didn't compile at all in VB.NET, apparently the type name DbNull was not possible to use in the context of Is, that's fine by me. I didn't like the syntax semantics but it was purely syntax, nothing else. So I tried to use the typeof operator:

Return IIF( value Is typeof(DbNull), 0, Convert.ToInt64(value) )

No compile there either, it turns out that typeof has to be before an Is statement and can only be applied to objects. Now why I would need typeof to work for objects when there is an object.GetType() eludes me but so far it's all about my inexperience with VB.NET syntax and its quirks (it also annoys me that there is a Mid when we have string.Substring in the framework but that is another post ). 

I found another keyword that supposedly would help me out; GetType, it works more like the typeof does in C# so I tried this out:

Return IIF(value is GetType(DbNull), 0, Convert.ToInt64(value) )

That actually compiled; joy! But function wise it failed miserably. The convert was always called regardless of the type the object variable contained. I factored out the type check to a regular If statement and discovered something that got me really puzzled.

If i changed it to Value Is GetType(object) it returned true. My god! It actually returned a check on the declaration of the parameter, not a check against the actual object type... That gave me a serious headache. Still using the factored out version I changed the type check again to instead make sure I get the concrete type out of the variable
:
If typeof ( value ) is DbNull then

That gave me the expected result, what a relief! My trip to VB World would soon be over. I refactored the code back to using the IIF function:

Return ( typeof ( value ) is DbNull, 0, Convert.ToInt64(value) )

I compiled and run it and it blew up in my face. GAH! Frustration! At this point I was about to give up, how is it possible that a type check that works in a regular If statement would fail in the IIF call!?

Some quick research gave me the answer, it didn't differ how the type check works. It turns out that the IIF function is one of the most stupid functions in the whole language. It does not care about your check at all; it goes ahead and evaluates both the false and the true part of the IIF statement regardless of the expression result.

Why would I want that kind of behavior? One of the reasons for using an if statement in the first place is to shield away the parts from each other, in my case it actually tried to convert to long although the check showed that it would not succeed.

A quick summary; type checks is really not intuitive in VB.NET, with special behaviors it actually confuses the heck out of programmers, no how's that for an "entry level language"? Additionally VB.NET functions are really stupid and doesn't do what they appear to do, they do something else. In a later post I'll show what =, Mid and other VB stuff really does.

Down with VB.NET! Long live C#!


 

Comments
4/14/2006 8:23:00 PM     -   Jeff Certain
 
You definitely went about it the hard way. A quick read of DbNull would have revealed DbNull.Value.

Been a while since I played with this, but your function should look like:

Return (value is dbnull.value, 0, Convert.ToInt64(value) )
 
4/14/2006 8:29:00 PM     -   Jeff Certain
 
BTW, VB.NET developers know how to use intellisense. Since Value is the only member of DbNull, this probably would have solved your problem.

Seems to me the problem in this case is with the developer, not the language.
 
4/14/2006 8:31:00 PM     -   Jeff Certain
 
BTW, VB.NET developers know how to use intellisense. Since Value is the only member of DbNull, this probably would have solved your problem.

Seems to me the problem in this case is with the developer, not the language.
 
4/15/2006 12:55:00 AM     -   [anonymous]
 
Even worse. Is is actually a different kind of = ? That IMHO is really bad, you can use Is to check for types but also for values? Now I do understand the semantics of Is, when checking for types it actually checks to see if the object types reference the same type object in the CLR. But using Is as =, my god it is really a screwed up language. Also IIF still has the same problem, it will evaluate the convert call no mather what.
 
5/3/2006 2:43:00 PM     -   Ola
 
You were really close there Patrik.
This is how to do it.

If IsDBNull(value) Then

Else

End If



RTFM/STFW ;)




 
5/3/2006 2:44:00 PM     -   Ola
 
You were really close there Patrik.
This is how to do it.

If IsDBNull(value) Then

Else

End If



RTFM/STFW ;)




 
5/3/2006 2:46:00 PM     -   Ola
 
Oh BTW, your blog crashes if I uncheck "Remember me"



 
3/26/2007 9:39:00 PM     -   Rockoon
 
OMG learn what IIF() is!!

I'll lay 9:1 that in the future you will also have trouble with Shared vs Static.

These confusions arise when a programmer from C# land jumps into VB.NET thinking hes big macho C# programmer so VB should be a snap.

IIF() is a FUNCTION (as is common in BASIC dialects) so its no suprise that it behaves like one.

The lack of a ternary operator in VB.NET is for sure something the language development team should be embarassed about, but at least they have an excuse (most other dialects don't have one either, and some legacy code relies on IIF() behaving the way it always has)
 
3/26/2007 10:20:00 PM   http://www.lowendahl.net   -   Patrik Löwendahl
 
Yes and that is exactly why VB suxx. It's is still function oriented.
 
4/28/2007 12:47:00 AM     -   Al
 
You're comparing apples and oranges; IIf() isn't even part of VB.Net; it's part of the old VB Interaction module, and generally speaking shouldn't be used. Most of us stopped using it even prior to .Net, as it caused an additional module to load, and evaluated both conditions, even if the first part evaluated to True.
 
4/29/2007 2:14:00 PM   http://www.lowendahl.net   -   Patrik Löwendahl
 
Not really.

IIF might be calling a function in the compat library. But it is still incorporated as part of the language and the compiler treats it as a syntax element.

That is pure wrong in my opinion. If it is a function it should be call as such:

like: lameCompat.IIf()


Comment
Title:
Your name:
Your url:
Text:
Please enter the text from the image: