Home All Groups Group Topic Archive Search About

Empty string comparisons

Author
25 Oct 2006 6:33 AM
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

Author
25 Oct 2006 9:42 AM
Pritcham
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 wrote:
Show quoteHide quote
> 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
Author
25 Oct 2006 2:30 PM
Oenone
Pritcham wrote:
> 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
///

--

(O)enone
Author
25 Oct 2006 1:16 PM
tommaso.gastaldi@uniroma1.it
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

Show quoteHide quote
>
> 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
Author
25 Oct 2006 1:58 PM
David Anton
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


Show quoteHide quote
"Neville Lang" wrote:

> 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
>
>
>
Author
26 Oct 2006 11:50 PM
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




Show quoteHide quote
"David Anton" <DavidAn***@discussions.microsoft.com> wrote in message
news:59A9EAC7-EE03-42AF-8D43-EE26682AC303@microsoft.com...
> 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
>
>
> "Neville Lang" wrote:
>
>> 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
>>
>>
>>
Author
25 Oct 2006 2:30 PM
Claes Bergefall
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

Show quoteHide quote
"Neville Lang" <neville@MAPS_ONnjlsoftware.com> wrote in message
news:ucODy9$9GHA.3348@TK2MSFTNGP03.phx.gbl...
> 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
>
>
Author
25 Oct 2006 2:47 PM
David Anton
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


Show quoteHide quote
"Claes Bergefall" wrote:

> 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
>
> "Neville Lang" <neville@MAPS_ONnjlsoftware.com> wrote in message
> news:ucODy9$9GHA.3348@TK2MSFTNGP03.phx.gbl...
> > 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
> >
> >
>
>
>
Author
26 Oct 2006 1:45 PM
Claes Bergefall
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

Show quoteHide quote
"David Anton" <DavidAn***@discussions.microsoft.com> wrote in message
news:63186DF2-8DE7-4EA4-9927-D6A755AD4596@microsoft.com...
> 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
>
>
> "Claes Bergefall" wrote:
>
>> 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
>>
>> "Neville Lang" <neville@MAPS_ONnjlsoftware.com> wrote in message
>> news:ucODy9$9GHA.3348@TK2MSFTNGP03.phx.gbl...
>> > 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
>> >
>> >
>>
>>
>>
Author
26 Oct 2006 2:25 PM
Jay B. Harlow
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.

--
Hope this helps
Jay B. Harlow
..NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


Show quoteHide quote
"Claes Bergefall" <louplou@nospam.nospam> wrote in message
news:%23f6zIUQ%23GHA.3644@TK2MSFTNGP02.phx.gbl...
> 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
>
> "David Anton" <DavidAn***@discussions.microsoft.com> wrote in message
> news:63186DF2-8DE7-4EA4-9927-D6A755AD4596@microsoft.com...
>> 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
>>
>>
>> "Claes Bergefall" wrote:
>>
>>> 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
>>>
>>> "Neville Lang" <neville@MAPS_ONnjlsoftware.com> wrote in message
>>> news:ucODy9$9GHA.3348@TK2MSFTNGP03.phx.gbl...
>>> > 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
>>> >
>>> >
>>>
>>>
>>>
>
>
Author
26 Oct 2006 9:28 PM
Jay B. Harlow
>> 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.
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...

--
Hope this helps
Jay B. Harlow
..NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


Show quoteHide quote
"Jay B. Harlow" <Jay_Harlow_***@tsbradley.net> wrote in message
news:27A229FC-862A-47A5-8527-A2FDAD88773B@microsoft.com...
> 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.
>
> --
> Hope this helps
> Jay B. Harlow
> .NET Application Architect, Enthusiast, & Evangelist
> T.S. Bradley - http://www.tsbradley.net
>
>
> "Claes Bergefall" <louplou@nospam.nospam> wrote in message
> news:%23f6zIUQ%23GHA.3644@TK2MSFTNGP02.phx.gbl...
>> 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
>>
>> "David Anton" <DavidAn***@discussions.microsoft.com> wrote in message
>> news:63186DF2-8DE7-4EA4-9927-D6A755AD4596@microsoft.com...
>>> 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
>>>
>>>
>>> "Claes Bergefall" wrote:
>>>
>>>> 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
>>>>
>>>> "Neville Lang" <neville@MAPS_ONnjlsoftware.com> wrote in message
>>>> news:ucODy9$9GHA.3348@TK2MSFTNGP03.phx.gbl...
>>>> > 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
>>>> >
>>>> >
>>>>
>>>>
>>>>
>>
>>
>
Author
26 Oct 2006 2:41 PM
David Anton
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


Show quoteHide quote
"Claes Bergefall" wrote:

> 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
>
> "David Anton" <DavidAn***@discussions.microsoft.com> wrote in message
> news:63186DF2-8DE7-4EA4-9927-D6A755AD4596@microsoft.com...
> > 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
> >
> >
> > "Claes Bergefall" wrote:
> >
> >> 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
> >>
> >> "Neville Lang" <neville@MAPS_ONnjlsoftware.com> wrote in message
> >> news:ucODy9$9GHA.3348@TK2MSFTNGP03.phx.gbl...
> >> > 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
> >> >
> >> >
> >>
> >>
> >>
>
>
>
Author
27 Oct 2006 1:55 PM
Claes Bergefall
Ahh, yes. The Is operator behaves different from the = operator.
VB is hilarious :-)

   /claes

Show quoteHide quote
"David Anton" <DavidAn***@discussions.microsoft.com> wrote in message
news:C21FAC70-9BA6-4FE4-A541-6C359ADD3EB4@microsoft.com...
> 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
>
>
> "Claes Bergefall" wrote:
>
>> 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
>>
>> "David Anton" <DavidAn***@discussions.microsoft.com> wrote in message
>> news:63186DF2-8DE7-4EA4-9927-D6A755AD4596@microsoft.com...
>> > 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
>> >
>> >
>> > "Claes Bergefall" wrote:
>> >
>> >> 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
>> >>
>> >> "Neville Lang" <neville@MAPS_ONnjlsoftware.com> wrote in message
>> >> news:ucODy9$9GHA.3348@TK2MSFTNGP03.phx.gbl...
>> >> > 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
>> >> >
>> >> >
>> >>
>> >>
>> >>
>>
>>
>>
Author
29 Oct 2006 5:47 PM
Jay B. Harlow
> 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...

--
Hope this helps
Jay B. Harlow
..NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


Show quoteHide quote
"Claes Bergefall" <louplou@nospam.nospam> wrote in message
news:e1XVM%23c%23GHA.924@TK2MSFTNGP03.phx.gbl...
> Ahh, yes. The Is operator behaves different from the = operator.
> VB is hilarious :-)
>
>   /claes
>
> "David Anton" <DavidAn***@discussions.microsoft.com> wrote in message
> news:C21FAC70-9BA6-4FE4-A541-6C359ADD3EB4@microsoft.com...
>> 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
>>
>>
>> "Claes Bergefall" wrote:
>>
>>> 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
>>>
>>> "David Anton" <DavidAn***@discussions.microsoft.com> wrote in message
>>> news:63186DF2-8DE7-4EA4-9927-D6A755AD4596@microsoft.com...
>>> > 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
>>> >
>>> >
>>> > "Claes Bergefall" wrote:
>>> >
>>> >> 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
>>> >>
>>> >> "Neville Lang" <neville@MAPS_ONnjlsoftware.com> wrote in message
>>> >> news:ucODy9$9GHA.3348@TK2MSFTNGP03.phx.gbl...
>>> >> > 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
>>> >> >
>>> >> >
>>> >>
>>> >>
>>> >>
>>>
>>>
>>>
>
>
Author
29 Oct 2006 9:30 PM
Göran_Andersson
Jay B. Harlow wrote:
> 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.
Author
30 Oct 2006 11:54 PM
Jay B. Harlow
Göran,
> What do you mean? The "=" operator is only used for equality, not
> identity.
Read the statement again, I was referring to C#:

If you don't override "=="  in C# it is used for identity (it reverts to the
IL equevilent of Object.ReferenceEquals); if you do override "=" then it
would (hopefully) be used for equality.

        public class Class1
        {
        }


            Class1 c1 = new Class1(), c2 = c1;
            Debug.WriteLine(c1 == c2);

--
Hope this helps
Jay B. Harlow
..NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


Show quoteHide quote
"Göran Andersson" <gu***@guffa.com> wrote in message
news:u%23il6F6%23GHA.3352@TK2MSFTNGP03.phx.gbl...
> Jay B. Harlow wrote:
>> 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.
Author
31 Oct 2006 9:40 PM
Göran_Andersson
Jay B. Harlow wrote:
Show quoteHide quote
> Göran,
>> What do you mean? The "=" operator is only used for equality, not
>> identity.
> Read the statement again, I was referring to C#:
>
> If you don't override "=="  in C# it is used for identity (it reverts to
> the IL equevilent of Object.ReferenceEquals); if you do override "="
> then it would (hopefully) be used for equality.
>
>        public class Class1
>        {
>        }
>
>
>            Class1 c1 = new Class1(), c2 = c1;
>            Debug.WriteLine(c1 == c2);
>

Of course it does. If you don't override the operator, it's inherited,
and that is the way that you compare two objects.

If you don't like it that way, you can always do it exactly the same way
VB does:

Debug.WriteLine(Microsoft.VisualBasic.CompilerServices.Operators.CompareObjectEqual(c1,c2));

The method is implemented as:

======

Public Shared Function CompareObjectEqual(ByVal Left As Object, ByVal
Right As Object, ByVal TextCompare As Boolean) As Object
       Dim class1 As CompareClass = Operators.CompareObject2(Left,
Right, TextCompare)
       Select Case class1
             Case CompareClass.Unordered
                   Return False
             Case CompareClass.UserDefined
                   Return
Operators.InvokeUserDefinedOperator(UserDefinedOperator.Equal, New
Object() { Left, Right })
             Case CompareClass.Undefined
                   Throw
Operators.GetNoValidOperatorException(UserDefinedOperator.Equal, Left,
Right)
       End Select
       Return (class1 = CompareClass.Equal)
End Function

======

The real work is done in the CompareObject2 method, which is implemented as:

======

Private Shared Function CompareObject2(ByVal Left As Object, ByVal Right
As Object, ByVal TextCompare As Boolean) As CompareClass
       Dim code1 As TypeCode
       Dim code2 As TypeCode
       Dim convertible1 As IConvertible = TryCast(Left,IConvertible)
       If (convertible1 Is Nothing) Then
             If (Left Is Nothing) Then
                   code1 = TypeCode.Empty
             Else
                   code1 = TypeCode.Object
             End If
       Else
             code1 = convertible1.GetTypeCode
       End If
       Dim convertible2 As IConvertible = TryCast(Right,IConvertible)
       If (convertible2 Is Nothing) Then
             If (Right Is Nothing) Then
                   code2 = TypeCode.Empty
             Else
                   code2 = TypeCode.Object
             End If
       Else
             code2 = convertible2.GetTypeCode
       End If
       If (code1 = TypeCode.Object) Then
             Dim chArray1 As Char() = TryCast(Left,Char())
             If ((Not chArray1 Is Nothing) AndAlso (((code2 =
TypeCode.String) OrElse (code2 = TypeCode.Empty)) OrElse ((code2 =
TypeCode.Object) AndAlso TypeOf Right Is Char()))) Then
                   Left = New String(chArray1)
                   convertible1 = DirectCast(Left, IConvertible)
                   code1 = TypeCode.String
             End If
       End If
       If (code2 = TypeCode.Object) Then
             Dim chArray2 As Char() = TryCast(Right,Char())
             If ((Not chArray2 Is Nothing) AndAlso ((code1 =
TypeCode.String) OrElse (code1 = TypeCode.Empty))) Then
                   Right = New String(chArray2)
                   convertible2 = DirectCast(Right, IConvertible)
                   code2 = TypeCode.String
             End If
       End If
       Select Case ((code1 * (TypeCode.String Or TypeCode.Object)) + code2)
             Case TypeCode.Empty
                   Return CompareClass.Equal
             Case TypeCode.Boolean
                   Return Operators.CompareBoolean(False,
convertible2.ToBoolean(Nothing))
             Case TypeCode.Char
                   Return Operators.CompareChar(ChrW(0),
convertible2.ToChar(Nothing))
             Case TypeCode.SByte
                   Return Operators.CompareInt32(0,
convertible2.ToSByte(Nothing))
             Case TypeCode.Byte
                   Return Operators.CompareInt32(0,
convertible2.ToByte(Nothing))
             Case TypeCode.Int16
                   Return Operators.CompareInt32(0,
convertible2.ToInt16(Nothing))
             Case TypeCode.UInt16
                   Return Operators.CompareInt32(0,
convertible2.ToUInt16(Nothing))
             Case TypeCode.Int32
                   Return Operators.CompareInt32(0,
convertible2.ToInt32(Nothing))
             Case TypeCode.UInt32
                   Return Operators.CompareUInt32(0,
convertible2.ToUInt32(Nothing))
             Case TypeCode.Int64
                   Return Operators.CompareInt64(CLng(0),
convertible2.ToInt64(Nothing))
             Case TypeCode.UInt64
                   Return Operators.CompareUInt64(0,
convertible2.ToUInt64(Nothing))
             Case TypeCode.Single
                   Return Operators.CompareSingle(0!,
convertible2.ToSingle(Nothing))
             Case TypeCode.Double
                   Return Operators.CompareDouble(0,
convertible2.ToDouble(Nothing))
             Case TypeCode.Decimal
                   Return
Operators.CompareDecimal(DirectCast(Decimal.Zero, IConvertible),
convertible2)
             Case TypeCode.DateTime
                   Return Operators.CompareDate(DateTime.MinValue,
convertible2.ToDateTime(Nothing))
             Case TypeCode.String
                   Return DirectCast(Operators.CompareString(Nothing,
convertible2.ToString(Nothing), TextCompare), CompareClass)
             Case DirectCast(57, TypeCode)
                   Return
Operators.CompareBoolean(convertible1.ToBoolean(Nothing), False)
             Case DirectCast(60, TypeCode)
                   Return
Operators.CompareBoolean(convertible1.ToBoolean(Nothing),
convertible2.ToBoolean(Nothing))
             Case DirectCast(62, TypeCode)
                   Return
Operators.CompareInt32(Operators.ToVBBool(convertible1),
convertible2.ToSByte(Nothing))
             Case DirectCast(63, TypeCode), DirectCast(64, TypeCode)
                   Return
Operators.CompareInt32(Operators.ToVBBool(convertible1),
convertible2.ToInt16(Nothing))
             Case DirectCast(65, TypeCode), DirectCast(66, TypeCode)
                   Return
Operators.CompareInt32(Operators.ToVBBool(convertible1),
convertible2.ToInt32(Nothing))
             Case DirectCast(67, TypeCode), DirectCast(68, TypeCode)
                   Return
Operators.CompareInt64(CLng(Operators.ToVBBool(convertible1)),
convertible2.ToInt64(Nothing))
             Case DirectCast(69, TypeCode), DirectCast(72, TypeCode)
                   Return
Operators.CompareDecimal(Operators.ToVBBoolConv(convertible1), convertible2)
             Case DirectCast(70, TypeCode)
                   Return
Operators.CompareSingle(CSng(Operators.ToVBBool(convertible1)),
convertible2.ToSingle(Nothing))
             Case DirectCast(71, TypeCode)
                   Return
Operators.CompareDouble(CDbl(Operators.ToVBBool(convertible1)),
convertible2.ToDouble(Nothing))
             Case DirectCast(75, TypeCode)
                   Return
Operators.CompareBoolean(convertible1.ToBoolean(Nothing),
Conversions.ToBoolean(convertible2.ToString(Nothing)))
             Case DirectCast(76, TypeCode)
                   Return
Operators.CompareChar(convertible1.ToChar(Nothing), ChrW(0))
             Case DirectCast(80, TypeCode)
                   Return
Operators.CompareChar(convertible1.ToChar(Nothing),
convertible2.ToChar(Nothing))
             Case DirectCast(94, TypeCode), DirectCast(346, TypeCode),
DirectCast(360, TypeCode)
                   Return
DirectCast(Operators.CompareString(convertible1.ToString(Nothing),
convertible2.ToString(Nothing), TextCompare), CompareClass)
             Case DirectCast(95, TypeCode)
                   Return
Operators.CompareInt32(convertible1.ToSByte(Nothing), 0)
             Case DirectCast(98, TypeCode)
                   Return
Operators.CompareInt32(convertible1.ToSByte(Nothing),
Operators.ToVBBool(convertible2))
             Case DirectCast(100, TypeCode)
                   Return
Operators.CompareInt32(convertible1.ToSByte(Nothing),
convertible2.ToSByte(Nothing))
             Case DirectCast(101, TypeCode), DirectCast(102, TypeCode),
DirectCast(119, TypeCode), DirectCast(121, TypeCode), DirectCast(138,
TypeCode), DirectCast(139, TypeCode), DirectCast(140, TypeCode)
                   Return
Operators.CompareInt32(convertible1.ToInt16(Nothing),
convertible2.ToInt16(Nothing))
             Case DirectCast(103, TypeCode), DirectCast(104, TypeCode),
DirectCast(123, TypeCode), DirectCast(141, TypeCode), DirectCast(142,
TypeCode), DirectCast(157, TypeCode), DirectCast(159, TypeCode),
DirectCast(161, TypeCode), DirectCast(176, TypeCode), DirectCast(177,
TypeCode), DirectCast(178, TypeCode), DirectCast(179, TypeCode),
DirectCast(180, TypeCode)
                   Return
Operators.CompareInt32(convertible1.ToInt32(Nothing),
convertible2.ToInt32(Nothing))
             Case DirectCast(105, TypeCode), DirectCast(106, TypeCode),
DirectCast(125, TypeCode), DirectCast(143, TypeCode), DirectCast(144,
TypeCode), DirectCast(163, TypeCode), DirectCast(181, TypeCode),
DirectCast(182, TypeCode), DirectCast(195, TypeCode), DirectCast(197,
TypeCode), DirectCast(199, TypeCode), DirectCast(201, TypeCode),
DirectCast(214, TypeCode), DirectCast(215, TypeCode), DirectCast(216,
TypeCode), DirectCast(217, TypeCode), DirectCast(218, TypeCode),
DirectCast(219, TypeCode), DirectCast(220, TypeCode)
                   Return
Operators.CompareInt64(convertible1.ToInt64(Nothing),
convertible2.ToInt64(Nothing))
             Case DirectCast(107, TypeCode), DirectCast(110, TypeCode),
DirectCast(129, TypeCode), DirectCast(145, TypeCode), DirectCast(148,
TypeCode), DirectCast(167, TypeCode), DirectCast(183, TypeCode),
DirectCast(186, TypeCode), DirectCast(205, TypeCode), DirectCast(221,
TypeCode), DirectCast(224, TypeCode), DirectCast(233, TypeCode),
DirectCast(235, TypeCode), DirectCast(237, TypeCode), DirectCast(239,
TypeCode), DirectCast(243, TypeCode), DirectCast(290, TypeCode),
DirectCast(291, TypeCode), DirectCast(292, TypeCode), DirectCast(293,
TypeCode), DirectCast(294, TypeCode), DirectCast(295, TypeCode),
DirectCast(296, TypeCode), DirectCast(297, TypeCode), DirectCast(300,
TypeCode)
                   Return Operators.CompareDecimal(convertible1,
convertible2)
             Case DirectCast(108, TypeCode), DirectCast(127, TypeCode),
DirectCast(146, TypeCode), DirectCast(165, TypeCode), DirectCast(184,
TypeCode), DirectCast(203, TypeCode), DirectCast(222, TypeCode),
DirectCast(241, TypeCode), DirectCast(252, TypeCode), DirectCast(253,
TypeCode), DirectCast(254, TypeCode), DirectCast(255, TypeCode),
DirectCast(256, TypeCode), DirectCast(257, TypeCode), DirectCast(258,
TypeCode), DirectCast(259, TypeCode), DirectCast(260, TypeCode),
DirectCast(262, TypeCode), DirectCast(298, TypeCode)
                   Return
Operators.CompareSingle(convertible1.ToSingle(Nothing),
convertible2.ToSingle(Nothing))
             Case DirectCast(109, TypeCode), DirectCast(128, TypeCode),
DirectCast(147, TypeCode), DirectCast(166, TypeCode), DirectCast(185,
TypeCode), DirectCast(204, TypeCode), DirectCast(223, TypeCode),
DirectCast(242, TypeCode), DirectCast(261, TypeCode), DirectCast(271,
TypeCode), DirectCast(272, TypeCode), DirectCast(273, TypeCode),
DirectCast(274, TypeCode), DirectCast(275, TypeCode), DirectCast(276,
TypeCode), DirectCast(277, TypeCode), DirectCast(278, TypeCode),
DirectCast(279, TypeCode), DirectCast(280, TypeCode), DirectCast(281,
TypeCode), DirectCast(299, TypeCode)
                   Return
Operators.CompareDouble(convertible1.ToDouble(Nothing),
convertible2.ToDouble(Nothing))
             Case DirectCast(113, TypeCode), DirectCast(132, TypeCode),
DirectCast(151, TypeCode), DirectCast(170, TypeCode), DirectCast(189,
TypeCode), DirectCast(208, TypeCode), DirectCast(227, TypeCode),
DirectCast(246, TypeCode), DirectCast(265, TypeCode), DirectCast(284,
TypeCode), DirectCast(303, TypeCode)
                   Return
Operators.CompareDouble(convertible1.ToDouble(Nothing),
Conversions.ToDouble(convertible2.ToString(Nothing)))
             Case DirectCast(114, TypeCode)
                   Return
Operators.CompareInt32(convertible1.ToByte(Nothing), 0)
             Case DirectCast(117, TypeCode)
                   Return
Operators.CompareInt32(convertible1.ToInt16(Nothing),
Operators.ToVBBool(convertible2))
             Case DirectCast(120, TypeCode)
                   Return
Operators.CompareInt32(convertible1.ToByte(Nothing),
convertible2.ToByte(Nothing))
             Case DirectCast(122, TypeCode), DirectCast(158, TypeCode),
DirectCast(160, TypeCode)
                   Return
Operators.CompareInt32(convertible1.ToUInt16(Nothing),
convertible2.ToUInt16(Nothing))
             Case DirectCast(124, TypeCode), DirectCast(162, TypeCode),
DirectCast(196, TypeCode), DirectCast(198, TypeCode), DirectCast(200,
TypeCode)
                   Return
Operators.CompareUInt32(convertible1.ToUInt32(Nothing),
convertible2.ToUInt32(Nothing))
             Case DirectCast(126, TypeCode), DirectCast(164, TypeCode),
DirectCast(202, TypeCode), DirectCast(234, TypeCode), DirectCast(236,
TypeCode), DirectCast(238, TypeCode), DirectCast(240, TypeCode)
                   Return
Operators.CompareUInt64(convertible1.ToUInt64(Nothing),
convertible2.ToUInt64(Nothing))
             Case DirectCast(133, TypeCode)
                   Return
Operators.CompareInt32(convertible1.ToInt16(Nothing), 0)
             Case DirectCast(136, TypeCode)
                   Return
Operators.CompareInt32(convertible1.ToInt16(Nothing),
Operators.ToVBBool(convertible2))
             Case DirectCast(152, TypeCode)
                   Return
Operators.CompareInt32(convertible1.ToUInt16(Nothing), 0)
             Case DirectCast(155, TypeCode)
                   Return
Operators.CompareInt32(convertible1.ToInt32(Nothing),
Operators.ToVBBool(convertible2))
             Case DirectCast(171, TypeCode)
                   Return
Operators.CompareInt32(convertible1.ToInt32(Nothing), 0)
             Case DirectCast(174, TypeCode)
                   Return
Operators.CompareInt32(convertible1.ToInt32(Nothing),
Operators.ToVBBool(convertible2))
             Case DirectCast(190, TypeCode)
                   Return
Operators.CompareUInt32(convertible1.ToUInt32(Nothing), 0)
             Case DirectCast(193, TypeCode)
                   Return
Operators.CompareInt64(convertible1.ToInt64(Nothing),
CLng(Operators.ToVBBool(convertible2)))
             Case DirectCast(209, TypeCode)
                   Return
Operators.CompareInt64(convertible1.ToInt64(Nothing), CLng(0))
             Case DirectCast(212, TypeCode)
                   Return
Operators.CompareInt64(convertible1.ToInt64(Nothing),
CLng(Operators.ToVBBool(convertible2)))
             Case DirectCast(228, TypeCode)
                   Return
Operators.CompareUInt64(convertible1.ToUInt64(Nothing), 0)
             Case DirectCast(231, TypeCode)
                   Return Operators.CompareDecimal(convertible1,
Operators.ToVBBoolConv(convertible2))
             Case DirectCast(247, TypeCode)
                   Return
Operators.CompareSingle(convertible1.ToSingle(Nothing), 0!)
             Case DirectCast(250, TypeCode)
                   Return
Operators.CompareSingle(convertible1.ToSingle(Nothing),
CSng(Operators.ToVBBool(convertible2)))
             Case DirectCast(266, TypeCode)
                   Return
Operators.CompareDouble(convertible1.ToDouble(Nothing), 0)
             Case DirectCast(269, TypeCode)
                   Return
Operators.CompareDouble(convertible1.ToDouble(Nothing),
CDbl(Operators.ToVBBool(convertible2)))
             Case DirectCast(285, TypeCode)
                   Return Operators.CompareDecimal(convertible1,
DirectCast(Decimal.Zero, IConvertible))
             Case DirectCast(288, TypeCode)
                   Return Operators.CompareDecimal(convertible1,
Operators.ToVBBoolConv(convertible2))
             Case DirectCast(304, TypeCode)
                   Return
Operators.CompareDate(convertible1.ToDateTime(Nothing), DateTime.MinValue)
             Case DirectCast(320, TypeCode)
                   Return
Operators.CompareDate(convertible1.ToDateTime(Nothing),
convertible2.ToDateTime(Nothing))
             Case DirectCast(322, TypeCode)
                   Return
Operators.CompareDate(convertible1.ToDateTime(Nothing),
Conversions.ToDate(convertible2.ToString(Nothing)))
             Case DirectCast(342, TypeCode)
                   Return
DirectCast(Operators.CompareString(convertible1.ToString(Nothing),
Nothing, TextCompare), CompareClass)
             Case DirectCast(345, TypeCode)
                   Return
Operators.CompareBoolean(Conversions.ToBoolean(convertible1.ToString(Nothing)),
convertible2.ToBoolean(Nothing))
             Case DirectCast(347, TypeCode), DirectCast(348, TypeCode),
DirectCast(349, TypeCode), DirectCast(350, TypeCode), DirectCast(351,
TypeCode), DirectCast(352, TypeCode), DirectCast(353, TypeCode),
DirectCast(354, TypeCode), DirectCast(355, TypeCode), DirectCast(356,
TypeCode), DirectCast(357, TypeCode)
                   Return
Operators.CompareDouble(Conversions.ToDouble(convertible1.ToString(Nothing)),
convertible2.ToDouble(Nothing))
             Case DirectCast(358, TypeCode)
                   Return
Operators.CompareDate(Conversions.ToDate(convertible1.ToString(Nothing)),
convertible2.ToDateTime(Nothing))
       End Select
       If ((code1 <> TypeCode.Object) AndAlso (code2 <>
TypeCode.Object)) Then
             Return CompareClass.Undefined
       End If
       Return CompareClass.UserDefined
End Function

======

Yeah, that is much better. ;)
Author
1 Nov 2006 12:42 AM
Jay B. Harlow
Göran,
> Of course it does. If you don't override the operator, it's inherited, and
> that is the way that you compare two objects.
"Of course it does" what? Are you now agreeing with me that C# uses the "=="
operator for both equality & identity? Unlike VB that has separate operators
for equality & identity?

> If you don't like it that way, you can always do it exactly the same way
> VB does:
As I stated earlier I can use "==" for (blurred) equality/identity in C# or
use Object.ReferenceEquals if I explicitly need identity in C#. I really
don't see the connection of a VB equality routine will help with Identity in
C#!

--
Hope this helps
Jay B. Harlow
..NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


Show quoteHide quote
"Göran Andersson" <gu***@guffa.com> wrote in message
news:eGGJdVT$GHA.3344@TK2MSFTNGP03.phx.gbl...
> Jay B. Harlow wrote:
>> Göran,
>>> What do you mean? The "=" operator is only used for equality, not
>>> identity.
>> Read the statement again, I was referring to C#:
>>
>> If you don't override "=="  in C# it is used for identity (it reverts to
>> the IL equevilent of Object.ReferenceEquals); if you do override "=" then
>> it would (hopefully) be used for equality.
>>
>>        public class Class1
>>        {
>>        }
>>
>>
>>            Class1 c1 = new Class1(), c2 = c1;
>>            Debug.WriteLine(c1 == c2);
>>
>
> Of course it does. If you don't override the operator, it's inherited, and
> that is the way that you compare two objects.
>
> If you don't like it that way, you can always do it exactly the same way
> VB does:
>
> Debug.WriteLine(Microsoft.VisualBasic.CompilerServices.Operators.CompareObjectEqual(c1,c2));
>
> The method is implemented as:
>
> ======
>
> Public Shared Function CompareObjectEqual(ByVal Left As Object, ByVal
> Right As Object, ByVal TextCompare As Boolean) As Object
>       Dim class1 As CompareClass = Operators.CompareObject2(Left, Right,
> TextCompare)
>       Select Case class1
>             Case CompareClass.Unordered
>                   Return False
>             Case CompareClass.UserDefined
>                   Return
> Operators.InvokeUserDefinedOperator(UserDefinedOperator.Equal, New
> Object() { Left, Right })
>             Case CompareClass.Undefined
>                   Throw
> Operators.GetNoValidOperatorException(UserDefinedOperator.Equal, Left,
> Right)
>       End Select
>       Return (class1 = CompareClass.Equal)
> End Function
>
> ======
>
> The real work is done in the CompareObject2 method, which is implemented
> as:
>
> ======
>
> Private Shared Function CompareObject2(ByVal Left As Object, ByVal Right
> As Object, ByVal TextCompare As Boolean) As CompareClass
>       Dim code1 As TypeCode
>       Dim code2 As TypeCode
>       Dim convertible1 As IConvertible = TryCast(Left,IConvertible)
>       If (convertible1 Is Nothing) Then
>             If (Left Is Nothing) Then
>                   code1 = TypeCode.Empty
>             Else
>                   code1 = TypeCode.Object
>             End If
>       Else
>             code1 = convertible1.GetTypeCode
>       End If
>       Dim convertible2 As IConvertible = TryCast(Right,IConvertible)
>       If (convertible2 Is Nothing) Then
>             If (Right Is Nothing) Then
>                   code2 = TypeCode.Empty
>             Else
>                   code2 = TypeCode.Object
>             End If
>       Else
>             code2 = convertible2.GetTypeCode
>       End If
>       If (code1 = TypeCode.Object) Then
>             Dim chArray1 As Char() = TryCast(Left,Char())
>             If ((Not chArray1 Is Nothing) AndAlso (((code2 =
> TypeCode.String) OrElse (code2 = TypeCode.Empty)) OrElse ((code2 =
> TypeCode.Object) AndAlso TypeOf Right Is Char()))) Then
>                   Left = New String(chArray1)
>                   convertible1 = DirectCast(Left, IConvertible)
>                   code1 = TypeCode.String
>             End If
>       End If
>       If (code2 = TypeCode.Object) Then
>             Dim chArray2 As Char() = TryCast(Right,Char())
>             If ((Not chArray2 Is Nothing) AndAlso ((code1 =
> TypeCode.String) OrElse (code1 = TypeCode.Empty))) Then
>                   Right = New String(chArray2)
>                   convertible2 = DirectCast(Right, IConvertible)
>                   code2 = TypeCode.String
>             End If
>       End If
>       Select Case ((code1 * (TypeCode.String Or TypeCode.Object)) + code2)
>             Case TypeCode.Empty
>                   Return CompareClass.Equal
>             Case TypeCode.Boolean
>                   Return Operators.CompareBoolean(False,
> convertible2.ToBoolean(Nothing))
>             Case TypeCode.Char
>                   Return Operators.CompareChar(ChrW(0),
> convertible2.ToChar(Nothing))
>             Case TypeCode.SByte
>                   Return Operators.CompareInt32(0,
> convertible2.ToSByte(Nothing))
>             Case TypeCode.Byte
>                   Return Operators.CompareInt32(0,
> convertible2.ToByte(Nothing))
>             Case TypeCode.Int16
>                   Return Operators.CompareInt32(0,
> convertible2.ToInt16(Nothing))
>             Case TypeCode.UInt16
>                   Return Operators.CompareInt32(0,
> convertible2.ToUInt16(Nothing))
>             Case TypeCode.Int32
>                   Return Operators.CompareInt32(0,
> convertible2.ToInt32(Nothing))
>             Case TypeCode.UInt32
>                   Return Operators.CompareUInt32(0,
> convertible2.ToUInt32(Nothing))
>             Case TypeCode.Int64
>                   Return Operators.CompareInt64(CLng(0),
> convertible2.ToInt64(Nothing))
>             Case TypeCode.UInt64
>                   Return Operators.CompareUInt64(0,
> convertible2.ToUInt64(Nothing))
>             Case TypeCode.Single
>                   Return Operators.CompareSingle(0!,
> convertible2.ToSingle(Nothing))
>             Case TypeCode.Double
>                   Return Operators.CompareDouble(0,
> convertible2.ToDouble(Nothing))
>             Case TypeCode.Decimal
>                   Return Operators.CompareDecimal(DirectCast(Decimal.Zero,
> IConvertible), convertible2)
>             Case TypeCode.DateTime
>                   Return Operators.CompareDate(DateTime.MinValue,
> convertible2.ToDateTime(Nothing))
>             Case TypeCode.String
>                   Return DirectCast(Operators.CompareString(Nothing,
> convertible2.ToString(Nothing), TextCompare), CompareClass)
>             Case DirectCast(57, TypeCode)
>                   Return
> Operators.CompareBoolean(convertible1.ToBoolean(Nothing), False)
>             Case DirectCast(60, TypeCode)
>                   Return
> Operators.CompareBoolean(convertible1.ToBoolean(Nothing),
> convertible2.ToBoolean(Nothing))
>             Case DirectCast(62, TypeCode)
>                   Return
> Operators.CompareInt32(Operators.ToVBBool(convertible1),
> convertible2.ToSByte(Nothing))
>             Case DirectCast(63, TypeCode), DirectCast(64, TypeCode)
>                   Return
> Operators.CompareInt32(Operators.ToVBBool(convertible1),
> convertible2.ToInt16(Nothing))
>             Case DirectCast(65, TypeCode), DirectCast(66, TypeCode)
>                   Return
> Operators.CompareInt32(Operators.ToVBBool(convertible1),
> convertible2.ToInt32(Nothing))
>             Case DirectCast(67, TypeCode), DirectCast(68, TypeCode)
>                   Return
> Operators.CompareInt64(CLng(Operators.ToVBBool(convertible1)),
> convertible2.ToInt64(Nothing))
>             Case DirectCast(69, TypeCode), DirectCast(72, TypeCode)
>                   Return
> Operators.CompareDecimal(Operators.ToVBBoolConv(convertible1),
> convertible2)
>             Case DirectCast(70, TypeCode)
>                   Return
> Operators.CompareSingle(CSng(Operators.ToVBBool(convertible1)),
> convertible2.ToSingle(Nothing))
>             Case DirectCast(71, TypeCode)
>                   Return
> Operators.CompareDouble(CDbl(Operators.ToVBBool(convertible1)),
> convertible2.ToDouble(Nothing))
>             Case DirectCast(75, TypeCode)
>                   Return
> Operators.CompareBoolean(convertible1.ToBoolean(Nothing),
> Conversions.ToBoolean(convertible2.ToString(Nothing)))
>             Case DirectCast(76, TypeCode)
>                   Return
> Operators.CompareChar(convertible1.ToChar(Nothing), ChrW(0))
>             Case DirectCast(80, TypeCode)
>                   Return
> Operators.CompareChar(convertible1.ToChar(Nothing),
> convertible2.ToChar(Nothing))
>             Case DirectCast(94, TypeCode), DirectCast(346, TypeCode),
> DirectCast(360, TypeCode)
>                   Return
> DirectCast(Operators.CompareString(convertible1.ToString(Nothing),
> convertible2.ToString(Nothing), TextCompare), CompareClass)
>             Case DirectCast(95, TypeCode)
>                   Return
> Operators.CompareInt32(convertible1.ToSByte(Nothing), 0)
>             Case DirectCast(98, TypeCode)
>                   Return
> Operators.CompareInt32(convertible1.ToSByte(Nothing),
> Operators.ToVBBool(convertible2))
>             Case DirectCast(100, TypeCode)
>                   Return
> Operators.CompareInt32(convertible1.ToSByte(Nothing),
> convertible2.ToSByte(Nothing))
>             Case DirectCast(101, TypeCode), DirectCast(102, TypeCode),
> DirectCast(119, TypeCode), DirectCast(121, TypeCode), DirectCast(138,
> TypeCode), DirectCast(139, TypeCode), DirectCast(140, TypeCode)
>                   Return
> Operators.CompareInt32(convertible1.ToInt16(Nothing),
> convertible2.ToInt16(Nothing))
>             Case DirectCast(103, TypeCode), DirectCast(104, TypeCode),
> DirectCast(123, TypeCode), DirectCast(141, TypeCode), DirectCast(142,
> TypeCode), DirectCast(157, TypeCode), DirectCast(159, TypeCode),
> DirectCast(161, TypeCode), DirectCast(176, TypeCode), DirectCast(177,
> TypeCode), DirectCast(178, TypeCode), DirectCast(179, TypeCode),
> DirectCast(180, TypeCode)
>                   Return
> Operators.CompareInt32(convertible1.ToInt32(Nothing),
> convertible2.ToInt32(Nothing))
>             Case DirectCast(105, TypeCode), DirectCast(106, TypeCode),
> DirectCast(125, TypeCode), DirectCast(143, TypeCode), DirectCast(144,
> TypeCode), DirectCast(163, TypeCode), DirectCast(181, TypeCode),
> DirectCast(182, TypeCode), DirectCast(195, TypeCode), DirectCast(197,
> TypeCode), DirectCast(199, TypeCode), DirectCast(201, TypeCode),
> DirectCast(214, TypeCode), DirectCast(215, TypeCode), DirectCast(216,
> TypeCode), DirectCast(217, TypeCode), DirectCast(218, TypeCode),
> DirectCast(219, TypeCode), DirectCast(220, TypeCode)
>                   Return
> Operators.CompareInt64(convertible1.ToInt64(Nothing),
> convertible2.ToInt64(Nothing))
>             Case DirectCast(107, TypeCode), DirectCast(110, TypeCode),
> DirectCast(129, TypeCode), DirectCast(145, TypeCode), DirectCast(148,
> TypeCode), DirectCast(167, TypeCode), DirectCast(183, TypeCode),
> DirectCast(186, TypeCode), DirectCast(205, TypeCode), DirectCast(221,
> TypeCode), DirectCast(224, TypeCode), DirectCast(233, TypeCode),
> DirectCast(235, TypeCode), DirectCast(237, TypeCode), DirectCast(239,
> TypeCode), DirectCast(243, TypeCode), DirectCast(290, TypeCode),
> DirectCast(291, TypeCode), DirectCast(292, TypeCode), DirectCast(293,
> TypeCode), DirectCast(294, TypeCode), DirectCast(295, TypeCode),
> DirectCast(296, TypeCode), DirectCast(297, TypeCode), DirectCast(300,
> TypeCode)
>                   Return Operators.CompareDecimal(convertible1,
> convertible2)
>             Case DirectCast(108, TypeCode), DirectCast(127, TypeCode),
> DirectCast(146, TypeCode), DirectCast(165, TypeCode), DirectCast(184,
> TypeCode), DirectCast(203, TypeCode), DirectCast(222, TypeCode),
> DirectCast(241, TypeCode), DirectCast(252, TypeCode), DirectCast(253,
> TypeCode), DirectCast(254, TypeCode), DirectCast(255, TypeCode),
> DirectCast(256, TypeCode), DirectCast(257, TypeCode), DirectCast(258,
> TypeCode), DirectCast(259, TypeCode), DirectCast(260, TypeCode),
> DirectCast(262, TypeCode), DirectCast(298, TypeCode)
>                   Return
> Operators.CompareSingle(convertible1.ToSingle(Nothing),
> convertible2.ToSingle(Nothing))
>             Case DirectCast(109, TypeCode), DirectCast(128, TypeCode),
> DirectCast(147, TypeCode), DirectCast(166, TypeCode), DirectCast(185,
> TypeCode), DirectCast(204, TypeCode), DirectCast(223, TypeCode),
> DirectCast(242, TypeCode), DirectCast(261, TypeCode), DirectCast(271,
> TypeCode), DirectCast(272, TypeCode), DirectCast(273, TypeCode),
> DirectCast(274, TypeCode), DirectCast(275, TypeCode), DirectCast(276,
> TypeCode), DirectCast(277, TypeCode), DirectCast(278, TypeCode),
> DirectCast(279, TypeCode), DirectCast(280, TypeCode), DirectCast(281,
> TypeCode), DirectCast(299, TypeCode)
>                   Return
> Operators.CompareDouble(convertible1.ToDouble(Nothing),
> convertible2.ToDouble(Nothing))
>             Case DirectCast(113, TypeCode), DirectCast(132, TypeCode),
> DirectCast(151, TypeCode), DirectCast(170, TypeCode), DirectCast(189,
> TypeCode), DirectCast(208, TypeCode), DirectCast(227, TypeCode),
> DirectCast(246, TypeCode), DirectCast(265, TypeCode), DirectCast(284,
> TypeCode), DirectCast(303, TypeCode)
>                   Return
> Operators.CompareDouble(convertible1.ToDouble(Nothing),
> Conversions.ToDouble(convertible2.ToString(Nothing)))
>             Case DirectCast(114, TypeCode)
>                   Return
> Operators.CompareInt32(convertible1.ToByte(Nothing), 0)
>             Case DirectCast(117, TypeCode)
>                   Return
> Operators.CompareInt32(convertible1.ToInt16(Nothing),
> Operators.ToVBBool(convertible2))
>             Case DirectCast(120, TypeCode)
>                   Return
> Operators.CompareInt32(convertible1.ToByte(Nothing),
> convertible2.ToByte(Nothing))
>             Case DirectCast(122, TypeCode), DirectCast(158, TypeCode),
> DirectCast(160, TypeCode)
>                   Return
> Operators.CompareInt32(convertible1.ToUInt16(Nothing),
> convertible2.ToUInt16(Nothing))
>             Case DirectCast(124, TypeCode), DirectCast(162, TypeCode),
> DirectCast(196, TypeCode), DirectCast(198, TypeCode), DirectCast(200,
> TypeCode)
>                   Return
> Operators.CompareUInt32(convertible1.ToUInt32(Nothing),
> convertible2.ToUInt32(Nothing))
>             Case DirectCast(126, TypeCode), DirectCast(164, TypeCode),
> DirectCast(202, TypeCode), DirectCast(234, TypeCode), DirectCast(236,
> TypeCode), DirectCast(238, TypeCode), DirectCast(240, TypeCode)
>                   Return
> Operators.CompareUInt64(convertible1.ToUInt64(Nothing),
> convertible2.ToUInt64(Nothing))
>             Case DirectCast(133, TypeCode)
>                   Return
> Operators.CompareInt32(convertible1.ToInt16(Nothing), 0)
>             Case DirectCast(136, TypeCode)
>                   Return
> Operators.CompareInt32(convertible1.ToInt16(Nothing),
> Operators.ToVBBool(convertible2))
>             Case DirectCast(152, TypeCode)
>                   Return
> Operators.CompareInt32(convertible1.ToUInt16(Nothing), 0)
>             Case DirectCast(155, TypeCode)
>                   Return
> Operators.CompareInt32(convertible1.ToInt32(Nothing),
> Operators.ToVBBool(convertible2))
>             Case DirectCast(171, TypeCode)
>                   Return
> Operators.CompareInt32(convertible1.ToInt32(Nothing), 0)
>             Case DirectCast(174, TypeCode)
>                   Return
> Operators.CompareInt32(convertible1.ToInt32(Nothing),
> Operators.ToVBBool(convertible2))
>             Case DirectCast(190, TypeCode)
>                   Return
> Operators.CompareUInt32(convertible1.ToUInt32(Nothing), 0)
>             Case DirectCast(193, TypeCode)
>                   Return
> Operators.CompareInt64(convertible1.ToInt64(Nothing),
> CLng(Operators.ToVBBool(convertible2)))
>             Case DirectCast(209, TypeCode)
>                   Return
> Operators.CompareInt64(convertible1.ToInt64(Nothing), CLng(0))
>             Case DirectCast(212, TypeCode)
>                   Return
> Operators.CompareInt64(convertible1.ToInt64(Nothing),
> CLng(Operators.ToVBBool(convertible2)))
>             Case DirectCast(228, TypeCode)
>                   Return
> Operators.CompareUInt64(convertible1.ToUInt64(Nothing), 0)
>             Case DirectCast(231, TypeCode)
>                   Return Operators.CompareDecimal(convertible1,
> Operators.ToVBBoolConv(convertible2))
>             Case DirectCast(247, TypeCode)
>                   Return
> Operators.CompareSingle(convertible1.ToSingle(Nothing), 0!)
>             Case DirectCast(250, TypeCode)
>                   Return
> Operators.CompareSingle(convertible1.ToSingle(Nothing),
> CSng(Operators.ToVBBool(convertible2)))
>             Case DirectCast(266, TypeCode)
>                   Return
> Operators.CompareDouble(convertible1.ToDouble(Nothing), 0)
>             Case DirectCast(269, TypeCode)
>                   Return
> Operators.CompareDouble(convertible1.ToDouble(Nothing),
> CDbl(Operators.ToVBBool(convertible2)))
>             Case DirectCast(285, TypeCode)
>                   Return Operators.CompareDecimal(convertible1,
> DirectCast(Decimal.Zero, IConvertible))
>             Case DirectCast(288, TypeCode)
>                   Return Operators.CompareDecimal(convertible1,
> Operators.ToVBBoolConv(convertible2))
>             Case DirectCast(304, TypeCode)
>                   Return
> Operators.CompareDate(convertible1.ToDateTime(Nothing), DateTime.MinValue)
>             Case DirectCast(320, TypeCode)
>                   Return
> Operators.CompareDate(convertible1.ToDateTime(Nothing),
> convertible2.ToDateTime(Nothing))
>             Case DirectCast(322, TypeCode)
>                   Return
> Operators.CompareDate(convertible1.ToDateTime(Nothing),
> Conversions.ToDate(convertible2.ToString(Nothing)))
>             Case DirectCast(342, TypeCode)
>                   Return
> DirectCast(Operators.CompareString(convertible1.ToString(Nothing),
> Nothing, TextCompare), CompareClass)
>             Case DirectCast(345, TypeCode)
>                   Return
> Operators.CompareBoolean(Conversions.ToBoolean(convertible1.ToString(Nothing)),
> convertible2.ToBoolean(Nothing))
>             Case DirectCast(347, TypeCode), DirectCast(348, TypeCode),
> DirectCast(349, TypeCode), DirectCast(350, TypeCode), DirectCast(351,
> TypeCode), DirectCast(352, TypeCode), DirectCast(353, TypeCode),
> DirectCast(354, TypeCode), DirectCast(355, TypeCode), DirectCast(356,
> TypeCode), DirectCast(357, TypeCode)
>                   Return
> Operators.CompareDouble(Conversions.ToDouble(convertible1.ToString(Nothing)),
> convertible2.ToDouble(Nothing))
>             Case DirectCast(358, TypeCode)
>                   Return
> Operators.CompareDate(Conversions.ToDate(convertible1.ToString(Nothing)),
> convertible2.ToDateTime(Nothing))
>       End Select
>       If ((code1 <> TypeCode.Object) AndAlso (code2 <> TypeCode.Object))
> Then
>             Return CompareClass.Undefined
>       End If
>       Return CompareClass.UserDefined
> End Function
>
> ======
>
> Yeah, that is much better. ;)
Author
1 Nov 2006 6:09 PM
Göran_Andersson
Jay B. Harlow wrote:
> Göran,
>> Of course it does. If you don't override the operator, it's inherited,
>> and that is the way that you compare two objects.
> "Of course it does" what? Are you now agreeing with me that C# uses the
> "==" operator for both equality & identity? Unlike VB that has separate
> operators for equality & identity?

The operator is used for equality. For the Object class it's the
references that are compared, which gives that it works the same as
comparing identity.

>> If you don't like it that way, you can always do it exactly the same
>> way VB does:
> As I stated earlier I can use "==" for (blurred) equality/identity in C#
> or use Object.ReferenceEquals if I explicitly need identity in C#. I
> really don't see the connection of a VB equality routine will help with
> Identity in C#!

Maybe I wasn't clear enough; that's the method that is called when you
use the "=" operator in VB.
Author
2 Nov 2006 1:45 AM
Jay B. Harlow
Göran,
> which gives that it works the same as comparing identity.
It sounds like we're quibbling over semantics. ;-)

If it looks like a rose, smells like a rose, tastes like a rose, feels like
a rose; I would say it must be a rose!

If it "works the same as comparing identity", would that not be the same as
stating is it identity? It does in my book! ;-)


--
Hope this helps
Jay B. Harlow
..NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


Show quoteHide quote
"Göran Andersson" <gu***@guffa.com> wrote in message
news:eAaO7De$GHA.1556@TK2MSFTNGP03.phx.gbl...
> Jay B. Harlow wrote:
>> Göran,
>>> Of course it does. If you don't override the operator, it's inherited,
>>> and that is the way that you compare two objects.
>> "Of course it does" what? Are you now agreeing with me that C# uses the
>> "==" operator for both equality & identity? Unlike VB that has separate
>> operators for equality & identity?
>
> The operator is used for equality. For the Object class it's the
> references that are compared, which gives that it works the same as
> comparing identity.
>
>>> If you don't like it that way, you can always do it exactly the same way
>>> VB does:
>> As I stated earlier I can use "==" for (blurred) equality/identity in C#
>> or use Object.ReferenceEquals if I explicitly need identity in C#. I
>> really don't see the connection of a VB equality routine will help with
>> Identity in C#!
>
> Maybe I wasn't clear enough; that's the method that is called when you use
> the "=" operator in VB.
Author
3 Nov 2006 12:00 AM
Göran_Andersson
Jay B. Harlow wrote:
> Göran,
>> which gives that it works the same as comparing identity.
> It sounds like we're quibbling over semantics. ;-)
>
> If it looks like a rose, smells like a rose, tastes like a rose, feels
> like a rose; I would say it must be a rose!
>
> If it "works the same as comparing identity", would that not be the same
> as stating is it identity? It does in my book! ;-)
>

Yes, it's semantics, that's why it isn't a rose just because it happens
to look like a rose from a certain angle. ;)

Just because it works like identity doesn't mean that it is identity.

If you have two integer that have the value two, and multiply them, you
get the result four. If you add them together you also get the result
four. That however does not mean that multiplying and adding is the same
thing in this case. They are still completely different operations
eventhough they give the same result.

Anyway, the difference between VB.NET and C# isn't really how comparison
works, but what comparison is used. While the C# compiler actually uses
the operator supplied by the Object class to compare Object instances,
VB uses the
Microsoft.VisualBasic.CompilerServices.Operators.CompareObjectEqual
method instead.
Author
3 Nov 2006 1:59 AM
Jay B. Harlow
Göran,
> Yes, it's semantics, that's why it isn't a rose just because it happens to
> look like a rose from a certain angle. ;)
OK, you haven't convinced me. :-|


> Just because it works like identity doesn't mean that it is identity.
OK, reading the C# specification states:

<quote src="http://msdn2.microsoft.com/en-us/library/53k8ybth.aspx">
For predefined value types, the equality operator (==) returns true if the
values of its operands are equal, false otherwise. For reference types other
than string, == returns true if its two operands refer to the same object.
For the string type, == compares the values of the strings.
</quote>

Last I checked Identity equality means "two operands refer to the same
object" as their identity is the reference itself.


> Anyway, the difference between VB.NET and C# isn't really how comparison
> works, but what comparison is used.
Now we're getting someplace.

VB "IS" operator compiles to an ceq IL opcode for any reference type, not
just System.Object variables.

C# "==" operator compiles to the same ceq IL opcode for any reference type,
not just System.Object variables, unless of course that reference type
overloads the "==" operator.

As you may know you need VB 2005 to gain the use of overloaded operators. In
which case C#'s overloaded "==" operator is VB's overloaded "=" comparison
operator. Neither VB nor C# allows you to overload the assignment operator
itself. VB does not allow you to overload the IS operator.


> While the C# compiler actually uses the operator supplied by the Object
> class to compare Object instances, VB uses the
> Microsoft.VisualBasic.CompilerServices.Operators.CompareObjectEqual
I'm sorry Göran; System.Object doesn't offer any operators!

As I stated earlier C# uses an IL opcode, the same opcode that is used (by
both VB & C#) for equality with types such as Int32, Byte, Double & other
"predefined value types".

Further C# uses the exactly same opcode for any reference type if you do not
overload the == operator! Such as my example of Class1! Compile and check
out the IL for the sample I gave earlier:

       public class Class1
        {
        }


            Class1 c1 = new Class1(), c2 = c1;
            Debug.WriteLine(c1 == c2);

Try the same in VB, with Option Strict On and with Option Strict Off

    Public Class Class1

    End Class

        Dim c1 As New Class1(), c2 = c1
        Debug.WriteLine(c1 = c2)

        Debug.WriteLine(c1 Is c2)

Try adding an overloaded  equality operator in both C# & VB

        public class Class1
        {
            public static bool operator ==(Class1 c1, Class1 c2)
            {
            }
            public static bool operator !=(Class1 c1, Class1 c2)
            {
            }
        }


    Public Class Class1

        Public Shared Operator =(ByVal c1 As Class1, ByVal c2 As Class1) As
Boolean

        End Operator

        Public Shared Operator <>(ByVal c1 As Class1, ByVal c2 As Class1) As
Boolean

        End Operator

    End Class

Compile both & examine the IL again.

Try the above for any number of reference types (Class), and any number of
value types (struct, Structure).

As far as I can tell CompareObjectEqual is only used when you have Option
Strict Off and only if both operands are System.Object types. If you have a
case where CompareObjectEqual is used with Option Strict On or used for
types other then System.Object I would love to see it!

To maximize compile errors over obscure runtime errors I normally use Option
Strict On. With Option Strict On the "=" comparison operator causes a
compile error in VB unless the type overloads the "=" operator. This means
that Int32, Byte, Double are allowed as are any types that VB implicitly
defines the operator for (such as Date) or the developer who defined the
type explicitly define the operator (such as TimeSpan). Some types, such as
String VB has defined its own equality operator that overrides String's =
operator. Option Strict On prohibits the "=" comparison operator on
reference types that do not overload the "=" comparison operator, this
includes System.Object!

--
Hope this helps
Jay B. Harlow
..NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


Show quoteHide quote
"Göran Andersson" <gu***@guffa.com> wrote in message
news:uaLrsst$GHA.3536@TK2MSFTNGP04.phx.gbl...
> Jay B. Harlow wrote:
>> Göran,
>>> which gives that it works the same as comparing identity.
>> It sounds like we're quibbling over semantics. ;-)
>>
>> If it looks like a rose, smells like a rose, tastes like a rose, feels
>> like a rose; I would say it must be a rose!
>>
>> If it "works the same as comparing identity", would that not be the same
>> as stating is it identity? It does in my book! ;-)
>>
>
> Yes, it's semantics, that's why it isn't a rose just because it happens to
> look like a rose from a certain angle. ;)
>
> Just because it works like identity doesn't mean that it is identity.
>
> If you have two integer that have the value two, and multiply them, you
> get the result four. If you add them together you also get the result
> four. That however does not mean that multiplying and adding is the same
> thing in this case. They are still completely different operations
> eventhough they give the same result.
>
> Anyway, the difference between VB.NET and C# isn't really how comparison
> works, but what comparison is used. While the C# compiler actually uses
> the operator supplied by the Object class to compare Object instances, VB
> uses the
> Microsoft.VisualBasic.CompilerServices.Operators.CompareObjectEqual method
> instead.
Author
26 Oct 2006 11:26 PM
Neville Lang
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



Show quoteHide quote
"Neville Lang" <neville@MAPS_ONnjlsoftware.com> wrote in message
news:ucODy9$9GHA.3348@TK2MSFTNGP03.phx.gbl...
> 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
>
>
Author
27 Oct 2006 11:56 AM
JimmyKoolPantz
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




Neville Lang wrote:
Show quoteHide quote
> 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
Author
29 Oct 2006 5:48 PM
Jay B. Harlow
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?

--
Hope this helps
Jay B. Harlow
..NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


Show quoteHide quote
"JimmyKoolPantz" <kohl.m***@gmail.com> wrote in message
news:1161950205.948797.180250@h48g2000cwc.googlegroups.com...
> 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
>
>
>
>
> Neville Lang wrote:
>> 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
>
Author
29 Oct 2006 9:43 PM
Göran_Andersson
Jay B. Harlow wrote:
> 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.

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.
Author
30 Oct 2006 11:32 PM
Jay B. Harlow
>> 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.
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.


--
Hope this helps
Jay B. Harlow
..NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


Show quoteHide quote
"Göran Andersson" <gu***@guffa.com> wrote in message
news:%23owFMN6%23GHA.3344@TK2MSFTNGP03.phx.gbl...
> Jay B. Harlow wrote:
>> 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.
>
> 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.