Empty string comparisons

  • Thread starter Thread starter Neville Lang
  • Start date Start date
N

Neville Lang

Hi all,

I am having a memory blank at the moment. I have been writing in C# for a
number of years and now need to do something in VB.NET, so forgive me such a
primitive question.

In C#, I test whether a string has a value or not by the following syntax:

if (thisString.Trim() == "")
{
// if true
something()
}
else
{
// if false
somethingelse()
}

Now, in VB.NET an equivalent does not seem to work:

If thisString.Trim() = "" Then
' if true
something()
Else
' if false
somethingelse()
End If

I cannot get past a False return for the VB comparison. What is the best
method for testing whether a string is empty or null?


Regards,
Neville Lang
 
Hi Neville

Don't know whether this is 'best' or not but it certainly works:

If testStr Is Nothing or Len(Trim(testStr)) = 0 Then
' 0 length or null string
Else
' string is initialised and not empty
End if

Cheers
Martin
 
Neville Lang ha scritto:

Now, in VB.NET an equivalent does not seem to work:

If thisString.Trim() = "" Then
' if true
something()
Else
' if false
somethingelse()
End If


I usually use:

Dim s As String = ""
If s.Trim = String.Empty Then
MsgBox("is empty")
Else
MsgBox("is not empty")
End If

but your version also looks fine to me (unless I am missing to see
something)...


Tommaso
 
Your problem probably lies elsewhere - the VB code you posted is the exact
equivalent to the C# code.
--
David Anton
www.tangiblesoftwaresolutions.com
Instant C#: VB to C# converter
Instant VB: C# to VB converter
Instant C++: C#/VB to C++ converter
Instant Python: VB to Python converter
 
Pritcham said:
Hi Neville

Don't know whether this is 'best' or not but it certainly works:

If testStr Is Nothing or Len(Trim(testStr)) = 0 Then
' 0 length or null string
Else
' string is initialised and not empty
End if

Just in case you're not aware, the Len() and Trim() functions understand
strings that are Nothing and treat them as empty strings (unlike
testStr.Length() or testStr.Trim(), which would obviously throw a
NullReferenceException), so you can actually shorten this to:

\\\
If Len(Trim(testStr)) = 0 Then
' 0 length or null string
Else
' string is initialised and not empty
End if
///
 
The code you have should work just fine. There are other ways to do it as
well though:

1. Use the VB.NET "feature" that null and empty string are considered equal
when using the = operator, i.e the following statement:
If thisString = "" Then
returns true if thisString is either empty *or* null (beware, this does not
work in C#)
2. Use the new String.IsNullOrEmpty method (requires .NET 2.0)

/claes
 
Regarding your first point, VB is even stranger than that:
A string set to Nothng (or uninitialized) is regarded as equal to an empty
string, but an empty string is *not* regarded as equal to Nothing. C# is
consistent in this respect: a null string is a null string and an empty
string is an empty string.
--
David Anton
www.tangiblesoftwaresolutions.com
Instant C#: VB to C# converter
Instant VB: C# to VB converter
Instant C++: C#/VB to C++ converter
Instant Python: VB to Python converter
 
Actually it does (at least in 2.0). All of the following evaluate to True:

Dim s1 As String = ""
Dim s2 As String = Nothing
Dim b1 As Boolean = (s1 = Nothing)
Dim b2 As Boolean = (s2 = Nothing)
Dim b3 As Boolean = (s1 = "")
Dim b4 As Boolean = (s2 = "")

You have to use String.Equals to distinguish between Nothing and an empty
string. Personally I find the VB.NET behaviour annoying and would prefer
that it worked the same as in C#

/claes
 
Claes,
You have to use String.Equals to distinguish between Nothing and an empty
string.
Close! ;-)

I would recommend using "Is" to distinguish between Nothing and an empty
string.
Dim b5 As Boolean = (s1 Is Nothing)
Dim b6 As Boolean = (s2 Is Nothing)

One might consider these two, however they won't always return true:
Dim b7 As Boolean = (s1 Is "")
Dim b8 As Boolean = (s2 Is "")

Depending on how s1 & s2 got to be an empty string will change what the last
two return.

For example:

s2 = " ".Trim()

Will cause (s2 Is "") to fail, as " ".Trim() returns a new string,
where as "" returns an interned string...

Remember that = does value equality ("" & Nothing) are considered to have
the same value.

Where as Is does reference equality ("", " ".Trim() & Nothing) are
distinct object references.
Personally I find the VB.NET behavior annoying and would prefer that it
worked the same as in C#
Most of the time I agree, there are times though where I prefer the C#
behavior.
 
Yes, but try:
Dim s1 As String = ""
Dim b1 As Boolean = (s1 Is Nothing)

b1 evaluates to false. Isn't VB fun?!
--
David Anton
www.tangiblesoftwaresolutions.com
Instant C#: VB to C# converter
Instant VB: C# to VB converter
Instant C++: C#/VB to C++ converter
Instant Python: VB to Python converter
 
Personally I find the VB.NET behavior annoying and would prefer that it
Most of the time I agree, there are times though where I prefer the C#
behavior.
Huh? (cringle nose).

That didn't come out right. :-) I meant most of the item I agree; Most of
the time I prefer the C# behavior. However there are times I like the VB
behavior...
 
HI all,

Thank you for your replies, they were helpful. From what I thought was a
fairly basic question, the responses did yield some interesting things in VB
v C#.

Regards,
Neville Lang
 
David,

To be fair on this question, there were some extra things that I did not
post in my example that would probably have affected the outcome. So, you
may be right in suspecting it might have been elsewhere. Here is the
complete picture:

Dim someError(259) As Byte
Dim thisString As String
Dim ret As Integer
....
....
' This function call is one located in a C++ DLL
' The someError argument had Marshaling setup as follows
' <MarshalAs(UnmanagedType.LPArray, SizeConst:=260)> ByVal someError As
Byte()
ret = externalFunction(a, b, c, someError)
thisString = Encoding.ASCII.GetString((someError)

' Now the string comparison. It was found that the
' string's return value was "" but its length was 260, and so all
' combinations of string comparison yielded a False in VB and
' that is why I asked my question.

It is from my Compact Framework experience in C# that I got into the habit
of setting up Byte arrays for returning error strings from external
functions in C++ DLLs, due to P/Invoke Marshaling restrictions in the
Compact Framework. And that is what I have continued here too.

After reading the various responses here, I feel I am now a bit more
knowledgeable on string comparisons.

Regards,
Neville Lang
 
There is a new declaration type of "Nullable" in vs2005 that I like to
use. For example:

Dim ThisString As Nullable(Of String) = Nothing


and when you want to check value of ThisString all you have to do is
use this syntax:

If ThisString.HasValue = True Then
'Do Something
End If
 
Ahh, yes. The Is operator behaves different from the = operator.
VB is hilarious :-)

/claes
 
Ahh, yes. The Is operator behaves different from the = operator.
VB is hilarious :-)
How so?

JavaScript has the Equality "==" (two equals) and the Identity "===" (three
equals) operators.

VB also has an Equality "=" (one equals) and an Identity "Is" operators.

Identity & Equality although very closely related are not synonymous.

What I find interesting is that JavaScript has a Non Identity operator "!=="
and VB 2005 introduced a Not Identity operator IsNot, but VB decided to
patent theirs...

I find it unfortunate & slightly confusing that C# blurs Equality with
Identity with a single operator "=" & "!="; Granted you can still use
Object.ReferenceEquals in C# for Identity...
 
Jimmy,
Dim ThisString As Nullable(Of String) = Nothing

Of course that causes a compile error as Nullable(Of T) can only be used
with types where T is a structure other then Nullable(Of) itself.

The rational being that String can already be Nothing; what does
ThisString.Value Is Nothing really mean?
 
Jay said:
I find it unfortunate & slightly confusing that C# blurs Equality with
Identity with a single operator "=" & "!="; Granted you can still use
Object.ReferenceEquals in C# for Identity...

What do you mean? The "=" operator is only used for equality, not identity.

The only time that you should find that confusing, is if you are already
confused.

If you for example have to references of type object, and they reference
strings, comparing them using the "=" operator of course compares the
object references, not the strings. If you want to compare the strings,
you have to specify that by casting the references.

If you are confused about what data types you are using, and what the
"=" operator for those datatypes do, of course the result of the
operation is also confusing.
 
Jay said:
Jimmy,

Of course that causes a compile error as Nullable(Of T) can only be used
with types where T is a structure other then Nullable(Of) itself.

Actually it's because string is not a value type.
The rational being that String can already be Nothing; what does
ThisString.Value Is Nothing really mean?

If the compiler would allow making nullables of objects, the variable
having a null value would be perfectly valid. It would be a bit
confusing and tedious to use, though, as the variable could have a value
and be null at the same time. You would first have to check that it has
a value, then check that the value is not null, before you could use the
value.
 
Of course that causes a compile error as Nullable(Of T) can only be used
Actually it's because string is not a value type.
You do realize we stated the same thing? I stated that Nullable(Of T)
requires a Value Type (aka a structure), while you confirmed that String is
not a value type.
 
Back
Top