Is there a difference between passing "" and passing Nothing to a Windows API ?

  • Thread starter Thread starter academic
  • Start date Start date
Dim s As String = String.Empty
...
s = DoSomething()
///

... initializing 's' is completely useless in the sample above and adds
additional initialization overhead. That's why I wrote that it doesn't
make sense to initialize /every/ string variable with 'String.Empty' or ""

Dim s As String = DoSomething()
is the answer.

Seems to me that you're still holding on to the VB.Classic notion of
"Declaring" variables at the top of a method rather Instantiating them when
you need them in a block so that they're destroyed when the block ends.

If Condition Then
Dim s As String = DoSomething()
'do work
End If

The benefits of this coding style are many and hard to explain unless you
work in a team or are otherwise mindful of future developers maintaining
your software. Curious, do you work in a team or alone?
 
Herfried K. Wagner said:
I'm curious why the compiler doesn't emit the same IL instruction for ""
it does for 'String.Empty'. Maybe this will change in a future version as
part of a compiler optimization.

They could do it as an optional "optimization" of sorts where the VB
compiler sees "" and replaces it with String.Empty (behind-the-scenes)
before compiling. But the reason of "why" is very clear. One is a literal
that has to be boxed and turned into an object in order to be used (because
that's the way stuff works) and the other is already an object.
 
One is a literal
that has to be boxed and turned into an object in order to be used (because
that's the way stuff works) and the other is already an object.

There's no boxing going on here, string is a reference type.


Mattias
 
According to "practical guidelines and best practices for Microsoft Visual
Basic and Visual C# Developers"

so by Francesco Balena and Giusseppe Dimauro and MS Press it is :-)

Then I guess I'll have to disagree with them, it wouldn't be the first
time.

Explicit assignment avoids NullReferenceException errors when referencing
the string and simplifies code ( because the string doesn`t have to be
tested against null )

I won't trade correctness for simplicity. Assigning "" to strings by
default, just to avoid NullReferenceExceptions, feels like a hack that
will just hide the actual problem. Exceptions can be good things if
they help you find errors during development, suppressing them is
taking the easy way out.

Do they also recommend catch-all exception handling (or On Error
Resume Next style programming)?


Mattias
 
Mattias Sjögren said:
There's no boxing going on here, string is a reference type.

A boxing is an object. That literal in your code isn't.
From MSDN:
Boxing is the process of converting a literal, like a single space, to the
implied object (in this case, a string object) for that literal.
 
I won't trade correctness for simplicity. Assigning "" to strings by
default, just to avoid NullReferenceExceptions, feels like a hack that
will just hide the actual problem.

Using VB's type emptystring type coercion is more of a hack. The actual
problem is that a string should mean something unless you really need it not
to. You don't have to initialize it to "" or String.Empty. You can
initialize it when you NEED it as so: Dim s As String = SomeMethod(). What's
wrong with that?
.... AND even better.... declare it inside blocks (If, Loops, etc) so it goes
out of scope at the end of the block. Man, this is just programming 101.

If VB developer's are still putting dozens of Dim's at the top of their
methods, boy, that doesn't bode well for the future of this platform. Dim in
VB.NET is not the same ol' VB.Classic Dim. They're missing out on the whole
point.
Exceptions can be good things if
they help you find errors during development, suppressing them is
taking the easy way out.

Initializing string is not suppressing an exception. Using Len(str) insetad
of str.Length *IS* suppressing it.

Fact is, pretty much the entire programming world has settled on the notion
that this is good practice. In C++ it's practically a law. In C# it's just a
darn good practice. It's only in VB where developers feel free to be
super-lazy and write horribly and hard to maintain code if they so wished
where this seems to be tolerated.
 
The performance differences aren't really noticeable but there IS a
difference!

Can you post some numbers?

If you have "" executed 50 times in your running code, you have created (and
instantly discarded) 50 object references. Sure, all the objects point to
the same string in the string table but still!

You make it sound like an object reference is an object in itself that
requires dynamic memory allocation. But they are just "pointers"
stored in preallocated space in registers, on the stack or in a field.
No dynamic allocation needed, so I don't see your point.


Mattias
 
Carlos,
Seems to me that you're still holding on to the VB.Classic notion of
"Declaring" variables at the top of a method rather Instantiating them
when you need them in a block so that they're destroyed when the block
ends.
This is not from the VB notation, it comes from the old days and is based on
the hardware type programming.

If you have to debug using the little bulps on a computer, than you are glad
that the data is seperated from the instructions and that you not have to
calculate a next program word what is behind x positions of data (or a
previous before).

I agree completely with you, that this is now without any sense and prefer
very much the way you describe.

I hope that it is clear what I write?

Cor
 
A boxing is an object. That literal in your code isn't.
From MSDN:
Boxing is the process of converting a literal, like a single space, to the
implied object (in this case, a string object) for that literal.


That quote seems to be from an article by Paul Sheriff, and he seems
to have come up with his own definition of the term boxing. That's
unfortunate, because if we don't have a common terminology it gets
pretty hard and confusing to discuss things like this.

The .NET framework docs have a different definition that I follow:

"The conversion of a value type instance to an object, which implies
that the instance will carry full type information at run time and
will be allocated on the heap."

http://msdn2.microsoft.com/en-us/library/b85sw2k8.aspx

See, nothing about literals and it specifically says value types.
Frankly I don't understand where Mr Sheriff his version from.


Mattias
 
I guess you'd have to understand what boxing means... semantically I guess.

Without knowledge of what a "value type" really is (a set of bytes--
otherwise known as intrinsic or primitive types) and how a string (an array
of bytes) is stored in a table and referenced by an "Object", then you would
be confused.

Again, that literal "" in your code does not refer to an object. It has to
be converted to (boxed? use whatever term you want to use) into an object.
 
You can
initialize it when you NEED it as so: Dim s As String = SomeMethod(). What's
wrong with that?

Nothing, I'm glad we finally agree on something. :) But that's not
what the original poster asked. And I guess people afraid of nulls
would still have to follow that line with

If s Is Nothing Then s = ""



Mattias
 
CMM said:
Using VB's type emptystring type coercion is more of a hack. The actual
problem is that a string should mean something unless you really need it
not to. You don't have to initialize it to "" or String.Empty. You can
initialize it when you NEED it as so: Dim s As String = SomeMethod().
What's wrong with that?
... AND even better.... declare it inside blocks (If, Loops, etc) so it
goes out of scope at the end of the block. Man, this is just programming
101.

If VB developer's are still putting dozens of Dim's at the top of their
methods, boy, that doesn't bode well for the future of this platform. Dim
in VB.NET is not the same ol' VB.Classic Dim. They're missing out on the
whole point.


Initializing string is not suppressing an exception. Using Len(str)
insetad of str.Length *IS* suppressing it.

I use 'Len' et al. to /intentionally/ suppress the exceptions if this is
semantically correct (samples given in previous posts).
Fact is, pretty much the entire programming world has settled on the
notion that this is good practice. In C++ it's practically a law. In C#
it's just a darn good practice. It's only in VB where developers feel free
to be super-lazy and write horribly and hard to maintain code if they so
wished where this seems to be tolerated.

In VB.NET people write 'If Len(s) > 0 Then' instead of 'if (s != null &&
s.Length > 0)' for example. I don't think this is a sign of laziness,
instead I consider it an important high-level programming feature which
helps simplifying code. BTW: I consider the rule "always assign an empty
string to string variables" lazy because it prevents the developer from
seeing potential problems.
 
helps simplifying code. BTW: I consider the rule "always assign an empty
string to string variables" lazy because it prevents the developer from
seeing potential problems.

I don't disagree.... my rule isn't to always initialize a string to Empty.
It's to always initialize it to something when I declare it. I try to
declare objects when I need them. You wouldn't see a bunch of Dim's that
don't initialize anything at the top my methods. That's VB.Classic
mentality. VB.NET's Dim is a whole new creature.

Anyhow, please describe "potential problems?" Like what? Give an example.
 
I agree.
It didn't help either that in VB.Classic (B.A.S.I.C. too?) Dim didn't
actually do anything (except I guess with arrays)... and it could appear
*anywhere* in your code, as long as it appeared just once (which wasn't even
really necessary either).

s = "hello"
Dim s As String

worked just fine:

Then again I remember when I could type:
IFLEN(X$)>0THENPRINT"HELLO"
(notice no spaces) on the Commodore and the parser knew EXACTLY what I was
doing. The good ol' days. ;-)
 
CMM said:
I don't disagree.... my rule isn't to always initialize a string to Empty.
It's to always initialize it to something when I declare it. I try to
declare objects when I need them. You wouldn't see a bunch of Dim's that
don't initialize anything at the top my methods. That's VB.Classic
mentality. VB.NET's Dim is a whole new creature.

Well, I used to declare variables directly in front of their first usage in
code even in Classic VB. By doing so, the compiler prevented me from
unintentionally assigning a value to the variable before it is actually used
in code.
Anyhow, please describe "potential problems?" Like what? Give an example.

I thought of unintentionally passing an empty string to a method when it
doesn't make sense for the method, for example. Many methods in the .NET
Framework throw 'NullReferenceExceptions' if 'Nothing' is passed to them in
a 'String' parameter because 'Nothing' doesn't make sense to this method.
The same applies to zero-length strings which do not contain data which is
meaningful to the method.
 
CMM said:
It didn't help either that in VB.Classic (B.A.S.I.C. too?) Dim didn't
actually do anything (except I guess with arrays)... and it could appear
*anywhere* in your code, as long as it appeared just once (which wasn't
even really necessary either).

s = "hello"
Dim s As String

.... which didn't compile in VB6, neither with 'Option Explicit' nor without
it.
worked just fine:

No, it didn't.
 
I seem to remember it being possible at some version (I didn't say VB6). If
not, I stand corrected.
Maybe I was thinking of some other macro or scripting lang in the past.
 
I thought of unintentionally passing an empty string to a method when it
doesn't make sense for the method, for example. Many methods in the .NET
Framework throw 'NullReferenceExceptions' if 'Nothing' is passed to them
in a 'String' parameter because 'Nothing' doesn't make sense to this
method. The same applies to zero-length strings which do not contain data
which is meaningful to the method.

Does this method throw an exception on empty strings as well? If not, you've
proved my point, not yours.
You can't give describe a concrete example why unitialized strings should be
the *norm* rather than the exception (pun intended)????

Here I'll give you one (that seemingly supports your case, but ultimately
proves mine (in the end)):

Setting an element in an XML document (or field in a dataset) to Nothing
causes it to not be rendered when the XML stream is rendered (either as a
file or otherwise). That's great- it's efficient for bandwidth reasons- and
it totally supports your case. The file might look like this

<persons>
<person>
<firstname>Joe</firstname>
<address>Some address</address>
<city>Some city</city>
<state>Some state</state>
</person>
<person>
<firstname>Tom</firstname>
<lastname>Jefferson</lastname>
<address>Some address</address>
<city>Some city</city>
<state>Some state</state>
</person>
</persons>

Notice the missing lastname in the first person element. That's great! What
could be wrong with that? Nothing if that was indeed your INTENTION. But if
your intention was to have a user load that sheet into Excel, you'd be in
for a surprise.... Excel renders the file as

firstname | address | city | state | lastname

Doh! That's not I wanted!

Again, Nothing is an "exceptional" thing that you should use when you NEED
it for a particular purpose. Don't use it just because the VB runtime allows
you to do all sorts of things on a Nothing-String.
 
Mattias Sjögren said:
Nothing, I'm glad we finally agree on something. :) And I guess
people afraid of nulls would still have to follow that line with
If s Is Nothing Then s = ""

Only if SomeMethod() was an XML or Database IO call.... or if SomeMethod()
were in a dependency written by Herfried Wagner (MVP). :-o

Otherwise, I'd assume the writers of SomeMethod were good coders. For
instance I wouldn't expect a Nothing returned from:
Dim s As String = PadMyString(x) where x might equal 0 times. But with
Herfried Wagner (maybe yours too?) code... anything is possible!
 
And to reiterate my statement about assumming that dependencies I might be
using were written by "good coders"
From MS Guidelines -
Array Usage Guidelines (BTW, a string is really an array)
Returning Empty Arrays
*String* and *Array* properties should never return a null reference. Null
can be difficult to understand in this context. For example, a user might
assume that the following code will work.
.... (obvious code sample)

I didn't add the emphasis. They did.

Obviously this isn't a "rule." Database IO calls return nulls all the time.
These are cases where you expect them... and they serve a particular
purpose. But, unless Nothing actually means something in your algorithm
OTHER than Empty, do the guys who might have to maintain your code in the
future or use your classes as a dependency and please initialize your poor
strings.
 
Back
Top