1

I have code where I get a string as input, and I compare it with an integer.

I saw that integer variable also has an Equals function that accepts a string parameter.

I have used it directly thinking it will typecast it.

It did not give any compile time or runtime error, but it always gives a false result.

For example,

int sessionId = 1;

string requestId="1"

return sessionId.Equals(requestId);

sessionId.Equals(requestId) always gives false.

Why is the reason for such behavior? If there is a reason, why are they allowing it run without error?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Imran Rizvi
  • 7,331
  • 11
  • 57
  • 101

5 Answers5

5

Integers and strings are always different, and thus "1".Equals(1) returns false.

It compiles because object.Equals(object other) takes an object as the right side, and thus accepts any type.

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
  • ya you are right!!, I think they should provide give a new function like .IsSameObject for object comparision. why to use equals everywhere? :) – Imran Rizvi Nov 21 '12 at 12:26
  • @ImranRizvi I don't know what you mean by `IsSameObject`. To check if two objects are the same instance, use `ReferenceEquals`. If you want `1` to equal `"1"` that's a bad idea IMO, but you can implement a custom `IEqualityComparer` that behaves that way. – CodesInChaos Nov 21 '12 at 12:28
3

The reason why this happens is that a string "0" is not the same as 0, so it returns false. Why is such behavior supported? Because the Equals method allows you to pass an object as a parameter, and a string is in an object, so you are "allowed" to do it. As you have found, it's not very useful in this case.

To solve your problem either get a string representation of the integer, or parse your string to an integer, then compare.

E.g. Try

    return (sessionId.ToString() == requestId);

or

    return (sessionId == int.Parse(requestId));

If you choose the later you may need to consider if the Parse could fail and how you might handle that.

Steve
  • 8,469
  • 1
  • 26
  • 37
1

Yes, Equals takes any type on the right side because it is requires an object. But inside the function it requires the same type as the left side. IMHO there's no need to throw an exception for type mismatching because one only wants to know about equality of two types.

Decompiled Equals of int:

public override bool Equals(object obj)
{
    return obj is int && this == (int)obj;
}
1

If someone shows you a car and a banana, and asks whether they are the same thing, would you throw a temper tantrum because a car is a vehicle and a banana is a fruit, or would you simply say "no, they are not the same thing"?

In many languages, trying to compare an integer and a string will yield a compiler error, because the compiler knows that the integer and the string cannot possibly be the same thing and thus any code that tried to compare them would almost certainly be erroneous. On the other hand, when you say sessionId.Equals(requestId), the compiler knows that you are asking that requestId be passed to the Int32 override of Equals. Since that override can accept a reference to any kind of heap object, it has no problem passing the string "1". That method in turn knows that it was given something which isn't the same as an Int32 with the value 1. It doesn't know that the calling code can't possibly supply anything that would match an Int32; all it knows is that the particular value isn't the same, and because the value isn't the same it perfectly happily returns false.

supercat
  • 77,689
  • 9
  • 166
  • 211
1

Shouldn’t we be using String.Compare for string comparison and forget about Equals?

I did have the same problem and I believe the function Equals should throw an exception. In my case, I have been comparing a string with a Boolean.

The discussion by now went wrong way. This is my view: If a comparison between objects belonging to two different classes always returns false, then they do not need to be compared in the first place.

If there is a need to have a function that bypasses type checking, there should be one. However, having the function Equals positioned as a recommended method for string comparison and in the same time introducing the possibility of unneeded bugs (which may sit in your program for eternity) is a kind of irresponsible. Moreover, it is extremely misleading that the function call String.Equals(string1, string2, StringComparison. xxx) also accepts non-string arguments. Thus not only string1.Equals(string2).

If that is by design, then it is a poor design.

Borjan
  • 23
  • 4