When "ToString" does not equal "ToString"

J

Jochen Kalmbach

Ayende said:
I've a really strange problem, in some part of my code I compare two
strings (through object), and while I *know* that they equal each
other, and in the watch window they do equal each other, then the
comparision return false.

See here for details:

http://www.ayende.com/Blog/PermaLink,guid,f5aa1a11-1710-434f-bfe0-39ac8
76a6acb.aspx

The problem is that "strings" are neither reference types nor value types!
They are handled in a special way...

In your case you are comparing object references which might be different!
Either use string.Compare(a, b) or a.CompareTo(b) or a.Equals(b)

--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
 
R

Richard Blewett [DevelopMentor]

The code that is failing is the

if( o == test) ?

well o and test are both typed as object so you are using the System.Object == operator which hands off to System.Object.ReferenceEquals. In other words, the comparison will onyl succeed if o and test are teh same physical object

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog

nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/<[email protected]>

I've a really strange problem, in some part of my code I compare two
strings (through object), and while I *know* that they equal each
other, and in the watch window they do equal each other, then the
comparision return false.

See here for details:

http://www.ayende.com/Blog/PermaLink,guid,f5aa1a11-1710-434f-bfe0-39ac876a6acb.aspx

---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.771 / Virus Database: 518 - Release Date: 28/09/2004



[microsoft.public.dotnet.languages.csharp]
 
R

Richard Blewett [DevelopMentor]

Umm, strings are reference types. They are immutable which results in some value like behavior but they are definitely reference types (i.e. allocated on the managed heap, referred to vai a 32 bit reference and are garbage collected.

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog

nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/<[email protected]>

Ayende said:
I've a really strange problem, in some part of my code I compare two
strings (through object), and while I *know* that they equal each
other, and in the watch window they do equal each other, then the
comparision return false.

See here for details:

http://www.ayende.com/Blog/PermaLink,guid,f5aa1a11-1710-434f-bfe0-39ac8
76a6acb.aspx

The problem is that "strings" are neither reference types nor value types!
They are handled in a special way...

In your case you are comparing object references which might be different!
Either use string.Compare(a, b) or a.CompareTo(b) or a.Equals(b)

--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/

---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.771 / Virus Database: 518 - Release Date: 28/09/2004



[microsoft.public.dotnet.languages.csharp]
 
J

Jon Skeet [C# MVP]

Jochen Kalmbach said:
The problem is that "strings" are neither reference types nor value types!
They are handled in a special way...

That's not true. String is a reference type which overrides operator==.

In what way do you believe they're not reference types?
 
J

Jochen Kalmbach

Jon said:
That's not true. String is a reference type which overrides
operator==.

In what way do you believe they're not reference types?

As Richard explains:
They are immutable which results in some value like behavior but they are
definitely reference types.

--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
 
R

Richard Blewett [DevelopMentor]

Ummm - thats where I went to find the if( o == test) piece of code. What do you mean by "this should never happen"? If you have two System.Object references compared by using the == operator then it will erform a reference check as I said becasue operator overloads are not virtual.

Regards

Richard Blewett - DevelopMentor

http://staff.develop.com/richardb/weblog

nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/<[email protected]>

Try here for a full sample, this should *never* happen.
http://www.ayende.com/Blog/PermaLink,guid,8153aa49-d1f1-4f48-9375-1c6f4d261dc0.aspx
 
J

Jon Skeet [C# MVP]

Jochen Kalmbach said:
As Richard explains:
They are immutable which results in some value like behavior but they are
definitely reference types.

Right. There's nothing particularly special about string being
immutable though - it's perfectly easy to write your own immutable
reference types, and it's often a good idea.
 
J

Jon Skeet [C# MVP]

<"=?Utf-8?B?QXllbmRlIFJhaGllbg==?=" <Ayende
Try here for a full sample, this should *never* happen.

http://www.ayende.com/Blog/PermaLink,guid,8153aa49-d1f1-4f48-9375-1c6
f4d261dc0.aspx

As Richard said, there's nothing mysterious here.

Just remember that operator overloading is considered at *compile*
time, not *run* time. (It's overloading, not overriding.) The compiler
doesn't know that o's value is actually going to be a reference to a
string.
 
J

Joakim Karlsson

Ayende said:
I've a really strange problem, in some part of my code I compare two
strings (through object), and while I *know* that they equal each
other, and in the watch window they do equal each other, then the
comparision return false.

See here for details:

http://www.ayende.com/Blog/PermaLink,guid,f5aa1a11-1710-434f-bfe0-39ac876a6acb.aspx

You are actually comparing two System.Object reference's, which IIRC
only checks if the two variables are referencing the same object.

Now, if one of your strings is not interned, this will fail. Try the
following:

foreach(Object o in enumerable)
{
string s1 = (string)o;
string s2 = (string)test;

if(String.IsInterned(s1) == null)
Console.WriteLine("s1 is not interned!");

if(String.IsInterned(s2) == null)
Console.WriteLine("s2 is not interned!");

if (o==test)
return;
}

If any of the two IsInterned checks fail, the comparison will fail.

HTH

Joakim
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top