4

Reading about string comparison in c# i found many ways to compare 2 strings to see if they are equal.

I was used to == coming from c++ but i learned that if you compare an object with a string then == defaults to reference value (or something like that).

Then for the Equals() method lets say i have 2 strings.

string s1 = null;
string s2 = "Hello";

if i do s1.Equals(s2);

I get an null-reference exception cause the first string is null

But if i do

string.equals(s1,s2);

It will simply return false if one of the values is null and if both the values are null it will return true since both strings would be equal in that they are both null.

So is there any reason not to always use the string.equals() method. Also another thing is that if i type the string.equals() with a capital S in the string like this String.equals() then it wll still run the same as if i had it lower case but the IDE (visual studio 2015) will tell me that it can be simplified and when i simplify it it turn it to a lower case s. Why is that?

Johnson
  • 401
  • 5
  • 14
  • Your understanding of `==` is wrong for C#. `==` for strings is going to be the same as `string.Equals()`. That is not true for Java, which may be the source of your mixup. – Glorin Oakenfoot Mar 25 '16 at 14:31
  • For the question `string` vs `String`: http://stackoverflow.com/questions/7074/whats-the-difference-between-string-and-string – xanatos Mar 25 '16 at 14:31
  • @glorin specify which `.Equals`! is going to be the same as the `static string.Equals(s1, s2)` – xanatos Mar 25 '16 at 14:31
  • 3
    You are providing a very obvious reason why you *don't* want to use String.Equals(). It hides a nasty bug in your code. Don't hide bugs. – Hans Passant Mar 25 '16 at 14:32
  • http://stackoverflow.com/questions/1659097/why-would-you-use-string-equals-over, http://stackoverflow.com/questions/7074/whats-the-difference-between-string-and-string – CodeCaster Mar 25 '16 at 14:32
  • Glorin well i am speaking generally about comparisons string is just for example. – Johnson Mar 25 '16 at 14:32
  • Hans what do you mean sorry i didn't understand. – Johnson Mar 25 '16 at 14:33
  • Note that the `Equals(string)` exists because a `string` is `IEquatable`, so to implement the interface. `Equals(object)` exists because it override the `object` method `Equals(object)` – xanatos Mar 25 '16 at 14:33
  • `s1` is `null`... It isn't referenced to anything, so you cannot call `s1.Equals` – J3soon Mar 25 '16 at 14:35
  • So what would be the recommended way to do comparisons in c# or does it have to do depending on the type compared? – Johnson Mar 25 '16 at 14:40
  • `s1.Equals(s2)` throws an exception when `s1` is null because you can't call an instance method on a null reference. – Jim Mischel Mar 25 '16 at 14:56
  • 1
    @sab669 unless you actually need to do a comparison, there's a severe performance hit using `String.Compare` vs `String.Equals` if you are checking for equality (and not actually comparing). May not be important while doing trivial operations, but might be very important if you have the need to check hundreds of thousands of strings in a tight loop. Checking for equality is much faster than comparing. – Jcl Mar 25 '16 at 16:03
  • @sab669 same thing actually, doing comparisons (other than byte-per-byte, which is what the non-overloaded `string.Equals` uses) that use the culture information are magnitudes of order less performant than byte equality (you can argue this, I haven't profiled, but the implementation of those is far more complicated and requires many lookups per character, so I'm quite positive it'll be). – Jcl Mar 25 '16 at 16:13

2 Answers2

4

According to MSDN, the string.Equals method

Determines whether two String objects have the same value.

This is why string.equals(s1,s2); would always return false in your case, and if both s1 and s2 are null or have the same value would return true.

Also another thing is that if i type the string.equals() with a capital S in the string like this String.equals() then it wll still run the same as if i had it lower case but the IDE (visual studio 2015) will tell me that it can be simplified and when i simplify it it turn it to a lower case s. Why is that?

The string is a C# primitive, while System.String or simple String is the corresponding FCL (Framework Class Library) type. It is the same like int and Int32, where int is a C# primitive and Int32 is the corresponding FLC type.

Christos
  • 53,228
  • 8
  • 76
  • 108
  • This is why string.equals(s1,s2); would always return true in your case, and if both s1 and s2 are null or have the same value would return false. You mean it would return true correct? – Johnson Mar 25 '16 at 14:42
  • @GeorgeOscStephan correct :( Thank you very much :) – Christos Mar 25 '16 at 15:00
  • Actually, `string` [is not a primitive type](http://stackoverflow.com/questions/3965752/is-string-a-primitive-type) in C# – bashis Mar 25 '16 at 15:07
3

Both methods perform these steps:

  1. Check if both strings share the same reference (and return true if they do). They do this by checking the object references (it does it by checking (object)a==(object)b: the == operator on two object variables only checks for reference). Note that this step also returns true if both objects are null.
  2. Check if either is null (and return false if any of them are)
  3. Check if both lengths match (and return false if they don't)
  4. If it comes to this point, it checks the bytes of each and see if they match (unless you have specified a type of StringComparison in one of the overloads) (side note: the byte comparison is implemented quite well and performant even being managed unsafe code... but this is an implementation detail that you shouldn't care about)

Whether you use one or the another (if you are sure your instance is not null) is up to you. Both basically do the same and they are equally performant.

Links to implementation: instance Equals method and static string.Equals

You can't call instance methods on null instances, which is why it's throwing a NullReferenceException for you... however the fact that your instance is null may be important (depending on your specifications), you may want to check for null before the comparison and act accordingly (using string.Equals would hide that away, and may be more bug-prone). If it isn't important to your specifications, then using one or the other is simply a design decision.

If you are interested, the operator == for two string types is implemented like (source link):

public static bool operator == (String a, String b) {
   return String.Equals(a, b);
}

So doing a == b is the same as doing string.Equals(a,b)

As for String and string, the former is System.String (which requires to have a using System; on top, or to specify the whole System.String.Equals), and the latter is a built-in alias (which doesn't require using System; on top). You can use either, they act exactly the same

Jcl
  • 27,696
  • 5
  • 61
  • 92