PC Review


Reply
Thread Tools Rate Thread

Single-Line If Statement Problem

 
 
=?Utf-8?B?RExQMjIxOTI=?=
Guest
Posts: n/a
 
      30th Apr 2005
I have the following single-line if statement that is evaluating true even
though it shouldn't. I have never seen this before and I am concerned that
this can happen in other areas of my code.

If String1.Length > 0 Then String2 = String1

where String1 = ""

This statement also evaluates as true when String1 = "":

If String1 <> "" Then String2 = String1

Changing the If statement to a multi-line If statement corrects the problem:

If String1.Length > 0 Then
String2 = String1
End If

Has anyone else seen this problem or know what's going on?

Thanks
 
Reply With Quote
 
 
 
 
Bob Lehmann
Guest
Posts: n/a
 
      30th Apr 2005
Using Single-Line If statements is a bad practice. If programming correctly
solves the problem, then what's the problem?

Bob Lehmann

"DLP22192" <(E-Mail Removed)> wrote in message
news:06FE86D4-DA72-4D39-ACFD-(E-Mail Removed)...
> I have the following single-line if statement that is evaluating true even
> though it shouldn't. I have never seen this before and I am concerned

that
> this can happen in other areas of my code.
>
> If String1.Length > 0 Then String2 = String1
>
> where String1 = ""
>
> This statement also evaluates as true when String1 = "":
>
> If String1 <> "" Then String2 = String1
>
> Changing the If statement to a multi-line If statement corrects the

problem:
>
> If String1.Length > 0 Then
> String2 = String1
> End If
>
> Has anyone else seen this problem or know what's going on?
>
> Thanks



 
Reply With Quote
 
 
 
 
Michael A. Covington
Guest
Posts: n/a
 
      30th Apr 2005
Can you give us a complete (short) program that demonstrates the problem?


"DLP22192" <(E-Mail Removed)> wrote in message
news:06FE86D4-DA72-4D39-ACFD-(E-Mail Removed)...
>I have the following single-line if statement that is evaluating true even
> though it shouldn't. I have never seen this before and I am concerned
> that
> this can happen in other areas of my code.
>
> If String1.Length > 0 Then String2 = String1
>
> where String1 = ""
>
> This statement also evaluates as true when String1 = "":
>
> If String1 <> "" Then String2 = String1
>
> Changing the If statement to a multi-line If statement corrects the
> problem:
>
> If String1.Length > 0 Then
> String2 = String1
> End If
>
> Has anyone else seen this problem or know what's going on?
>
> Thanks



 
Reply With Quote
 
=?Utf-8?B?QU1lcmNlcg==?=
Guest
Posts: n/a
 
      30th Apr 2005
I don't buy it. I stepped through the code below, and none of the conditions
evaluated to true. Your description of the problem is leaving something out.
Dim s1 As String
Dim s2 As String
s1 = ""
s2 = "x"
If s1.Length > 0 Then s2 = s1
s2 = "x"
If s1 <> "" Then s2 = s1
s2 = "x"
If s1.Length > 0 Then
s2 = s1
End If


"DLP22192" wrote:

> I have the following single-line if statement that is evaluating true even
> though it shouldn't. I have never seen this before and I am concerned that
> this can happen in other areas of my code.
>
> If String1.Length > 0 Then String2 = String1
>
> where String1 = ""
>
> This statement also evaluates as true when String1 = "":
>
> If String1 <> "" Then String2 = String1
>
> Changing the If statement to a multi-line If statement corrects the problem:
>
> If String1.Length > 0 Then
> String2 = String1
> End If
>
> Has anyone else seen this problem or know what's going on?
>
> Thanks

 
Reply With Quote
 
Stephany Young
Guest
Posts: n/a
 
      1st May 2005
Oooooh, Oooooh, I do!

What you are seeing is the VB.Net equivalent of an optical illusion. To
demonstrate -

Try this:

Dim _string1 As String

Console.WriteLine(_string1 Is Nothing)

Console.WriteLine(_string1 = "")

Console.WriteLine(_string1.Length = 0)

The results should be:

True
True
Exception (Object reference not set to an instance of an object)

"But,", I hear you ask, "if the 3rd Console.WriteLine threw an exception
then why didn't the 2nd Console.WriteLine throw an exception also?".

Good question. I don't fully understand why, but if you 'query' the value of
an uninitialised variable whose Type is a 'Value Type' then the value
returned is default value for that Type, but the variable itself stays
uninitialised.

Now try:

Dim _string1 As String = String.Empty

Console.WriteLine(_string1 Is Nothing)

Console.WriteLine(_string1 = "")

Console.WriteLine(_string1.Length = 0)

The results should be:

False
True
True

This is what we we would expect for an initialised string variable. The
variable is initialised so it is not Nothing, it's value is an empty string
and it's length is 0.

What you don't show us is the code that initialised your String1 variable,
but I will bet that it was initialised from a array of bytes or something
like that.

The ASCII characters in the range 0 to 31 can cause unexpected problems for
the uninitiated, especially the NUL character (ASCII 0) which can be
represented by the ControlChars.NullChar constant.

If you 'look' at a string that contains one or more of these, you will only
'see' the characters that precede the first instance of it.

Try this:

Dim _string1 As String = "abc" & ControlChars.NullChar & "def"


Console.WriteLine(_string1.Length)

Console.WriteLine(_string1)

While one might expect to see the results displayed as

6
abcdef

The actual results will be:

7
abc

Note that everything after the NUL character has been suppressed.

Now try:

Dim _string1 As String = ControlChars.NullChar

Console.WriteLine(_string1.Length)

Console.Writeline(_string1 = "")

Console.WriteLine(_string1)

The result is:

1
False

The 2nd Console.Writeline appears to have got it wrong because the 3rd one
displayed a blank line. In fact, the 3rd one only appeared to display a
blank line - it actually displayed nothing at all because of the NUL
character.

NUL character often find their way into strings that have been 'loaded' from
byte arrays but the NUL character is also often used as a delimiter.

If you suspect that there might be NUL characters in a string then you must
handle them correctly.

One way to get get rid of leading and/or trailing NUL characters is to use:

_string1 = string1.Trim(ControlChars.NullChar)

One way to get get rid of imbedded NUL characters is to use:

_string1 = _string1.Replace(ControlChars.NullChar, String.Empty)

The conclusion is that you should never assume that a string varaible has
any given value.

Test, Test, Test!


"DLP22192" <(E-Mail Removed)> wrote in message
news:06FE86D4-DA72-4D39-ACFD-(E-Mail Removed)...
>I have the following single-line if statement that is evaluating true even
> though it shouldn't. I have never seen this before and I am concerned
> that
> this can happen in other areas of my code.
>
> If String1.Length > 0 Then String2 = String1
>
> where String1 = ""
>
> This statement also evaluates as true when String1 = "":
>
> If String1 <> "" Then String2 = String1
>
> Changing the If statement to a multi-line If statement corrects the
> problem:
>
> If String1.Length > 0 Then
> String2 = String1
> End If
>
> Has anyone else seen this problem or know what's going on?
>
> Thanks



 
Reply With Quote
 
Jon Skeet [C# MVP]
Guest
Posts: n/a
 
      1st May 2005
Stephany Young <noone@localhost> wrote:
> Oooooh, Oooooh, I do!
>
> What you are seeing is the VB.Net equivalent of an optical illusion. To
> demonstrate -
>
> Try this:
>
> Dim _string1 As String
>
> Console.WriteLine(_string1 Is Nothing)
>
> Console.WriteLine(_string1 = "")
>
> Console.WriteLine(_string1.Length = 0)
>
> The results should be:
>
> True
> True
> Exception (Object reference not set to an instance of an object)
>
> "But,", I hear you ask, "if the 3rd Console.WriteLine threw an exception
> then why didn't the 2nd Console.WriteLine throw an exception also?".


That's because VB.NET has overloaded the = operator for strings, and
when comparing strings, considers null (Nothing) and the empty string
as being the same. (It doesn't strike me as a good thing, but there we
go.) Here's part of the specs (from section 11.14, Relational
Operators):

<quote>
String. The operators return the result of comparing the two values
using either a binary comparison or a text comparison. The comparison
used is determined by the compilation environment and the Option
Compare statement. A binary comparison determines whether the numeric
Unicode value of each character in each string is the same. A text
comparison does a Unicode text comparison based on the current culture
in use on the .NET Framework. When doing a string comparison, a null
reference is equivalent to the string literal "".
</quote>

> Good question. I don't fully understand why, but if you 'query' the value of
> an uninitialised variable whose Type is a 'Value Type' then the value
> returned is default value for that Type, but the variable itself stays
> uninitialised.


Note that string isn't a value type, by the way.

<snip>

> Try this:
>
> Dim _string1 As String = "abc" & ControlChars.NullChar & "def"
>
>
> Console.WriteLine(_string1.Length)
>
> Console.WriteLine(_string1)
>
> While one might expect to see the results displayed as
>
> 6
> abcdef
>
> The actual results will be:
>
> 7
> abc
>
> Note that everything after the NUL character has been suppressed.


Not on my box. On mine I get:

7
abc def

(which is what I'd expect).

There used to be a bug in the debugger which would terminate strings on
null characters, and certainly various GUI elements assume null
termination, but the console doesn't.

--
Jon Skeet - <(E-Mail Removed)>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
 
Reply With Quote
 
Stephany Young
Guest
Posts: n/a
 
      1st May 2005
I stand educated

And, yes, I was running my examples in the IDE (Debug) rather than a
console.


"Jon Skeet [C# MVP]" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Stephany Young <noone@localhost> wrote:
>> Oooooh, Oooooh, I do!
>>
>> What you are seeing is the VB.Net equivalent of an optical illusion. To
>> demonstrate -
>>
>> Try this:
>>
>> Dim _string1 As String
>>
>> Console.WriteLine(_string1 Is Nothing)
>>
>> Console.WriteLine(_string1 = "")
>>
>> Console.WriteLine(_string1.Length = 0)
>>
>> The results should be:
>>
>> True
>> True
>> Exception (Object reference not set to an instance of an object)
>>
>> "But,", I hear you ask, "if the 3rd Console.WriteLine threw an exception
>> then why didn't the 2nd Console.WriteLine throw an exception also?".

>
> That's because VB.NET has overloaded the = operator for strings, and
> when comparing strings, considers null (Nothing) and the empty string
> as being the same. (It doesn't strike me as a good thing, but there we
> go.) Here's part of the specs (from section 11.14, Relational
> Operators):
>
> <quote>
> String. The operators return the result of comparing the two values
> using either a binary comparison or a text comparison. The comparison
> used is determined by the compilation environment and the Option
> Compare statement. A binary comparison determines whether the numeric
> Unicode value of each character in each string is the same. A text
> comparison does a Unicode text comparison based on the current culture
> in use on the .NET Framework. When doing a string comparison, a null
> reference is equivalent to the string literal "".
> </quote>
>
>> Good question. I don't fully understand why, but if you 'query' the value
>> of
>> an uninitialised variable whose Type is a 'Value Type' then the value
>> returned is default value for that Type, but the variable itself stays
>> uninitialised.

>
> Note that string isn't a value type, by the way.
>
> <snip>
>
>> Try this:
>>
>> Dim _string1 As String = "abc" & ControlChars.NullChar & "def"
>>
>>
>> Console.WriteLine(_string1.Length)
>>
>> Console.WriteLine(_string1)
>>
>> While one might expect to see the results displayed as
>>
>> 6
>> abcdef
>>
>> The actual results will be:
>>
>> 7
>> abc
>>
>> Note that everything after the NUL character has been suppressed.

>
> Not on my box. On mine I get:
>
> 7
> abc def
>
> (which is what I'd expect).
>
> There used to be a bug in the debugger which would terminate strings on
> null characters, and certainly various GUI elements assume null
> termination, but the console doesn't.
>
> --
> Jon Skeet - <(E-Mail Removed)>
> http://www.pobox.com/~skeet
> If replying to the group, please do not mail me too



 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
vba: How do I write a "For Each Statement" nested in a "With Statement"? Mcasteel Microsoft Excel Programming 1 8th Nov 2004 10:47 PM
vba: How do I write a "For Each Statement" nested in a "With Statement"? Mcasteel Microsoft Excel Programming 0 8th Nov 2004 10:47 PM
vba: How do I write a "For Each Statement" nested in a "With Statement"? Mcasteel Microsoft Excel Programming 1 8th Nov 2004 10:23 PM
vba: How do I write a "For Each Statement" nested in a "With Statement"? Mcasteel Microsoft Excel Programming 0 8th Nov 2004 10:08 PM
vba: How do I write a "For Each Statement" nested in a "With Statement"? Mcasteel Microsoft Excel Programming 0 8th Nov 2004 09:58 PM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 07:43 PM.