string == and Equals

P

Peter K

Hi

Is there any way that the following to statements could give different
results?

I have 2 strings (s1 and s2), which if I compare with == are not equal, but
if I compare with string.Equals, then they are equal.

string.Equals(s1, s2) is true

s1 == s2 is false


All this happens really deep down in an application I am testing. So I
haven't yet worked out what is going on, I'd just like a bit of sanity
feedback (I always though that == and Equals on strings were the same).


Thanks,
Peter
 
P

Peter K

Is there any way that the following to statements could give different
results?

I have 2 strings (s1 and s2), which if I compare with == are not
equal, but if I compare with string.Equals, then they are equal.

string.Equals(s1, s2) is true

s1 == s2 is false

I have now found out why. Of course the objects are "objects" not
"strings". Even though they are string values, they are of type object - I
just hadn't seen that.
 
J

Jon Skeet [C# MVP]

I have now found out why. Of course the objects are "objects" not
"strings". Even though they are string values, they are of type object - I
just hadn't seen that.

I suspect what you mean is that either s1, s2 or both of them are
declared as type object. If they were declared as string variables,
you'd see the correct result.

Jon
 
P

Peter K

I suspect what you mean is that either s1, s2 or both of them are
declared as type object. If they were declared as string variables,
you'd see the correct result.


Yes, both s1 and s2 are of type object.

The original programmer uses a test like this in his code:

if (s1 == s2)

and this resulted in "true" as he had earlier set s1 and s2 like this:

s1 = s2 = "cow";

(s1 and s2 are actually instance variable of container class)

I was trying to use his component, and passed two strings which came via
WCF, and although they were equal strings, they were not ==.

So it could be that via WCF, something like the following happened:
char[] v1 = new char[] { 'c', 'o', 'w' };
char[] v2 = new char[] { 'c', 'o', 'w' };
object s1 = new String(v1);
object s2 = new String(v2);

I'm totally guessing, but I can see that with my objects, the test

if (s1 == s2) is false

while if the test had been something like

if (object.Equals(s1, s2)) then it would have been true.

In the end this results in a totally different output. I am not quite
sure how to fix this issue actually.


(This was all part of a large, complex program, generating a complex
search tree and took me many hours to find!)



/Peter
 
J

Jon Skeet [C# MVP]

Peter K said:
Yes, both s1 and s2 are of type object.

Are they both known to be strings? If so, that's the easiest way to fix
it - declare them as string variables instead of object variables, and
it'll work fine.
 
P

Peter K

Are they both known to be strings? If so, that's the easiest way to fix
it - declare them as string variables instead of object variables, and
it'll work fine.

I don't know if they are "always" strings. I don't understand the entirity
of the program, or how it is used :-(

I've sent a begging email to the original programmer, asking about this
(and hoping I can make this simple change), and I hope he replies :)

Thanks,
Peter
 
M

Marc Gravell

In that case, try the static "object.Equals(x,y)" method... this tests
for referential equality, and (if not) checks whether they both are
non-null, then uses x.Equals(y)

It is probably your best bet if you don't know the types and aren't
using generics.

Marc
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,


A dirty workaround is trying to convert them to string:
string s = o as string;

string s1 = o1 as string;



and then check if any of them is null, if so at least one of them was not
an string
 
P

Peter Duniho

I suspect what you mean is that either s1, s2 or both of them are
declared as type object. If they were declared as string variables,
you'd see the correct result.

And please, remind me again, why is it that the == operator doesn't just
automatically use Object.Equals()?

I'm sure there's a good reason, but it's escaping me at the moment. It
seems pretty relevant to the question though.

Pete
 
C

christery

I'm sure there's a good reason, but it's escaping me at the moment.  It  
seems pretty relevant to the question though.

Pete

Oh you men that theae are too red cars and you ask
are both cars red? = true
are they the same car?= false
//CY
 
J

Jon Skeet [C# MVP]

Peter Duniho said:
And please, remind me again, why is it that the == operator doesn't just
automatically use Object.Equals()?

I'm sure there's a good reason, but it's escaping me at the moment. It
seems pretty relevant to the question though.

Good question. There are any number of interesting things you can do
with operator overloading, although I'm not sure of the merit of them.
For instance, == doesn't actually have to return a bool. It could
return a Nullable<bool> if you wanted nullable logic, or do even more
bizarre things:

using System;

class Test
{
public static string operator== (Test t1, Test t2)
{
return "wow!";
}

public static string operator!= (Test t1, Test t2)
{
return "ick!";
}

static void Main()
{
Test t1 = new Test();
Test t2 = new Test();

Console.WriteLine(t1==t2);
Console.WriteLine(t1!=t2);
}
}

How odd is that?
 
P

Peter Duniho

Good question. There are any number of interesting things you can do
with operator overloading, although I'm not sure of the merit of them.

I thought in C# you couldn't overload the == operator. That was the
source of my confusion.

I don't know where I got that idea (maybe because the assignment operator
can't be overloaded), but yes...I agree that given that == can be
overloaded, you can't rely on it always calling Object.Equals(). I was
under the mistaken impression that this was something the compiler could
have implemented.

I guess that's the "good reason" to which I referred. :)

Pete
 
R

Registered User

And please, remind me again, why is it that the == operator doesn't just
automatically use Object.Equals()?

I'm sure there's a good reason, but it's escaping me at the moment. It
seems pretty relevant to the question though.
It might be because one is an overloaded operator and the other is a
base class method.

regards
A.G.
 
C

christery

Good question. There are any number of interesting things you can do
with operator overloading, although I'm not sure of the merit of them.
For instance, == doesn't actually have to return a bool. It could
return a Nullable<bool> if you wanted nullable logic, or do even more
bizarre things:

using System;

class Test
{
    public static string operator== (Test t1, Test t2)
    {
        return "wow!";
    }

    public static string operator!= (Test t1, Test t2)
    {
        return "ick!";
    }

    static void Main()
    {
        Test t1 = new Test();
        Test t2 = new Test();

        Console.WriteLine(t1==t2);
        Console.WriteLine(t1!=t2);
    }

}

How odd is that?

Well It wont work with reserved words (I think)... didnt try it but
pretty shure, == and != arent reserved as I remember.. just operators
and operators can be overloaded
//CY
 
J

Jon Skeet [C# MVP]

On Jan 25, 9:20 am, (e-mail address removed) wrote:

Well It wont work with reserved words (I think)... didnt try it but
pretty shure, == and != arent reserved as I remember.. just operators
and operators can be overloaded

Yes, but that's just begging Peter's question as to *why* they can be
overloaded, rather than the compiler just generating code which calls
object.Equals(x, y). Reference equality is rarely useful (and can be
explicitly checked with object.ReferenceEquals).

Overloading == is nice for value types of course, as it avoids boxing.

For reference types, I suspect there aren't many situations where
you'd want == and != to behave differently to a call to object.Equals.
I suppose it avoids a virtual call, which could be slightly handy in
terms of performance... on the other hand, it *makes* the call non-
virtual, which can be a pain. Mind you, equality comparisons up and
down a type hierarchy are painful anyway.

Jon
 
C

christery

Yeah but for mocking up a project if you get pissed this is great...
the wow/ick code shows just what (has been sold out by) letting
operators to be overloaded causes

still I think there is the q
is two cars red
and is those the same car?
are we looking at values or references...

But Im not too shure I understood the q.

Think my english is mysterius? I can answwe in mienkieli instead...

//CY Who tooh away chr$(12)?
 
J

Jon Skeet [C# MVP]

Yeah but for mocking up a project if you get pissed this is great...
the wow/ick code shows just what (has been sold out by) letting
operators to be overloaded causes

still I think there is the q
is two cars red
and is those the same car?
are we looking at values or references...

And that depends on whether or not == has been overloaded. If you want
to be sure, use object.Equals or object.ReferenceEquals.
 
C

christery

And that depends on whether or not == has been overloaded. If you want
to be sure, use object.Equals or object.ReferenceEquals.

Nope, I trust noone in my projects get pissed enough to do that...
and what would you thik if you saw someone using Equals insted of ==?
thinking HE MIGHT be overloading it (==) somwhere else... WTF...
where

Think I will stick to basic/dos... clears the head

10 print chr$(12)
20 goto 10

Ahh...
 

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