views:

136

answers:

3

I usually define my string variables in vb.net as

Dim f_sName as string=String.Empty
f_sName = "foo"

Given the immutable nature of strings in .net, is there a better way to initialize strings and deal with the "Variable 'f_sName ' is used before it has been assigned a value. A null reference exception could result at runtime." warning?

Also for classes that do not have constructors which accept no arguments such as System.Net.Sockets.NetworkStream, what is the best way to define and initialize a variable of that type?

All comments are highly appreciated.

Thanks

+1  A: 

Initializing a string to null and to String.Empty are pretty much the same thing. Personally, I think setting it to string.empty really is the best way of handling it. Setting it to null will result in throwing null reference exceptions though where as setting it to String.Empty will not.

One can argue the merits of initializing it one of two ways, but optimization wise there is no discernible difference.

Kevin
Null (Noting) an Empty ("") are not the same.
Henk Holterman
Technically, no, but for most people they represent the same idea. If not, MS would never have created the ISNullOrEmpty. People most feel they are interchangeable. You are right setting it to null with through a null reference exception.
Kevin
But 'same idea' is not in the spirit of this particular question. It does matter (sometimes) which one you pick for an initialization.
Henk Holterman
" If not, MS would never have created the ISNullOrEmpty". I don't think Microsoft introduced IsNullOrEmpty in .NET 2.0 because most people think a null string and an empty string are interchangeable. Nor did they introduce IsNullOrWhitespace in .NET 4.0 because a string containing only whitespace characters is interchangeable with a null string. Of course the distinction between null and an empty string is sometimes (not always) important - in fact the need for this distinction drove the introduction of Nullable value types in .NET 2.0.
Joe
@joe: strings were already nullable. And once again, it does matter when initializing, NullOrEmpty is the other side of the medal.
Henk Holterman
+1  A: 
Dim f_sName as String = Nothing

or

Dim f_sName As New String()

By the way: mixing mixedCase variable naming with underscores (as in f_sName) looks strange most of the time, what does this variable name stand for?

ChristopheD
The first f indicates the scope of the variable. f= function/procedure level, m= module level, g = global.The underscore is just a separator for readability. The s is the variable type, in this case, string. and the remaining characters are a descriptive identifier indicating the contents of a string. How do you name your variables?
klork
I've not seen this in .net code yet (looks dangerous when the scope indicator turns inconsistent when you move code around). This might be an interesting read: http://10rem.net/articles/net-naming-conventions-and-programming-standards---best-practices
ChristopheD
+1  A: 

This has nothing to do with the strings being immutable.

A better preferable pattern would be

 Dim f_sName as string = "Foo"

But it depends on the situation if you can use that.

Same for initializing with Nothing or Empty. If you want to catch errors early, then:

  1. just don't initialize at all. "Variable 'xxx' is used before it has been assigned a value" is your friend, not your enemy.
  2. Initialize with Nothing. It too might bring errors to light.
  3. Initialize with Empty (or just "", no difference).

And concerning classes like NetworkStream, same thing: don't create instance and don't declare variables until you need them. For a Disposable class like NetworkStream this means use a Using clause:

 Using fs As New NetworkStream(....)

 End Using

It is neither desirable nor useful to have 'fs' available outside that narrow scope.

Henk Holterman
In case we follow the philosophy of declaring variables only when we need them, would that not mean variables declared in a try block would not be available in the catch block?
klork
@klork, yes, and I do acknowledge that that can be a valid concern. But it should not be a normal pattern. In the catch block you need the exception object. If you find yourself managing other (disposable) objects in a catch block, refactoring to a(nother) nesting of Using and Try/Catch might make the whole problem go away.
Henk Holterman