Difference between == and Equals in C# [duplicate] - c#

This question already has answers here:
Closed 10 years ago.
The community reviewed whether to reopen this question 11 months ago and left it closed:
Original close reason(s) were not resolved
Possible Duplicate:
C# difference between == and .Equals()
For comparing two variables we can use == or Equals method. for example,
string a = new string(new char[] {'a', 'b', 'c', 'd'});
string b = new string(new char[] {'a', 'b', 'c', 'd'});
Console.WriteLine (a==b);
Console.WriteLine (a.Equals(b));
My question is When should I use == and when should I use Equals? Is there any difference between the two?

== is an operator, which, when not overloaded means "reference equality" for classes (and field-wise equality for structs), but which can be overloaded. A consequence of it being an overload rather than an override is that it is not polymorphic.
Equals is a virtual method; this makes it polymorphic, but means you need to be careful not to call it on null instances.
As a rule of thumb:
if you know the type of something, and know it has an == overload (most core types such as string, int, float, etc have == meanings), then use ==
if you don't know the type, Equals(a,b) may be recommended, as this avoids the null issue
if you really want to check for the same instance (reference equality), consider using ReferenceEquals(a,b), as this will work even if the == is overloaded and Equals overridden
when using generics, consider EqualityComparer<T>.Default.Equals(a,b) which avoids the null issue, supports Nullable-of-T, and supports IEquatable-of-T

This post by John Skeet will answer your question:
So, when should you use which operator? My rule of thumb is that for
almost all reference types, use Equals when you want to test equality
rather than reference identity. The exception is for strings -
comparing strings with == does make things an awful lot simpler and
more readable but you need to remember that both sides of the operator
must be expressions of type string in order to get the comparison to
work properly.
For value types, I'd normally use == for easier-to-read code. Things
would get tricky if a value type provided an overload for == which
acted differently to Equals, but I'd consider such a type very badly
designed to start with.
[Author: Jon Skeet]
http://blogs.msdn.com/b/csharpfaq/archive/2004/03/29/when-should-i-use-and-when-should-i-use-equals.aspx

When == is used on an object type, it'll resolve to
System.Object.ReferenceEquals.
Equals is just a virtual method and behaves as such, so the overridden
version will be used (which, for string type compares the contents).
https://stackoverflow.com/a/814880/655293

Related

Why do string datatypes always perform value comparison

I was looking for the difference between == and .Equals methods in C# and I found that the first one compares the object references, and the second one compares the objects values, except for the string datatypes both == and .Equals() does a content comparison. I can't really find an explanation for that, is it because the string datatypes are immutable ?
Here's what I want to say
object obj1 = "Test";
object obj2 = new string("Test".ToCharArray());
Console.WriteLine(obj1.Equals(obj2) + " " + (obj1 == obj2));
string a = "Test";
string b = "Test";
Console.WriteLine(a.Equals(b) + " "+ (a == b));
Output
True False
True True
In fact for the first comparison we have two different objects with same value and we got as result True and false, but for the case of string we have true for both comparison
This isn't true at all. == is an overridable operator, and Equals is an overridable method. It's up to the class to define how each of them behaves.
Perhaps you're confusing C# with Java?
If you want to do a reference comparison, use object.ReferenceEquals. Everything else is implementation dependant (though note that operator overrides are checked statically, so e.g. (object)someString == (object)someOtherString will do a reference comparison, not a value comparison; Equals doesn't have this "problem").
Most often, both == and Equals are designed to give the same answer (though == is always stricter about types in the comparison, as mentioned before). This applies double for structs, where a reference comparison doesn't really make much of a sense anyway.
And of course, the compiler doesn't actually do any checks. If I want, I can override the == operator to always return false. Or to only check some ID for equality. Or to change the objects being compared, if you are feeling particularly evil. In the end, it's just a static method like any other (with a few restrictions).
EDIT:
To address your edit directly, string always performs a content comparison because both its == and Equals are overriden to perform a content comparison. However, that doesn't mean that it always performs a costly char-by-char comparison - if you look how string.Equals is actually implemented, you can see that it tries a few things to avoid the costly comparison:
If the string is null, they must be different
If the two strings are reference-equal, they must also be content-equal
If the two strings don't have the same length, they must be different
You can see the actual by-value comparison method here - http://referencesource.microsoft.com/#mscorlib/system/string.cs,11648d2d83718c5e A simple piece of unsafe code, but manually written code nevertheless. There's no automatic value comparison in .NET (though there's tricks that come close).
It's because it makes sense.
Java couldn't do it this way because it doesn't have operator overloading, but that's no argument in C#.
This isn't unique to strings, by the way. Any type could overload the == operator to do something similar.
Any object can override/overload Equals or ==, so they can behave however the library author wants them to behave.

Difference between String1.Equals(string2) and string1==string2 C# [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
C#: String.Equals vs. ==
Are string.Equals() and == operator really same?
sometimes in a condition between two strings, I write:
if(string1==string2) //Do something
and sometimes I write:
if(string1.Equals(string2)) //Do something
The problem is sometimes the first one doesn't work, or miswork, is there any difference between the two expressions?
The first one will always work so long as the compile-time type of both operands is string.
If the compile-time type of either operand is anything other than string, it will use the normal reference identity comparison, rather than comparing strings for equality. Basically you want to call the ==(string, string) overload instead of the normal ==(object, object) overload.
Note that the first will succeed even if string1 is null, whereas the second will throw NullReferenceException in that case. An alternative in order to preserve the Equals call but avoiding this problem is to call the static object.Equals(object, object) method:
if (object.Equals(string1, string2))
Personally I'd just use == in cases where the compile-time types are appropriate though.
The use of == on two string types will perform a reference identity check, meaning it will only return true if both references point to the same object. Equals on the other hand is expected to perform a value comparison, and will return true if the references point to objects that are equivalent.

C# == is different in value types and reference types?

In Java there are "==" and "equals" operator for reference types and "==" for value types. for reference type, "==" means both objects point to the same location and "equals" means their values are the same. does C# has similar operators for value type and reference types?
Well, == can be overloaded for reference types. For example:
string a = new string('x', 10);
string b = new string('x', 10);
Console.WriteLine(a == b); // True
Console.WriteLine(Object.ReferenceEquals(a, b)); // False
Unless it's overloaded, == means "reference equality" aka "object identity" for reference types. (As Marc says, you may override Equals without overloading ==.)
For value types, you have to overload == otherwise the C# compiler won't let you use it for comparisons. .NET itself will provide an implementation of Equals which usually does the right thing, but sometimes slowly - in most cases, if you write your own custom value type you'll want to implement IEquatable<T> and override Equals as well - and quite possibly overload various operators.
C# allows the == operator to be overloaded (and the Equals method to be overridden - although == and Equals don't have to mean the same thing).
If you want to mean "the same instance", then object.ReferenceEquals (for reference-types) is the best option. Value types default to internal equality.
Straight out of MSDN:
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.
Jon Skeet should be able to give you a perfect answer though :P
When should I use == and when should I use Equals?
http://blogs.msdn.com/csharpfaq/archive/2004/03/29/102224.aspx
This is precisely the way it works with .NET as well. The C# FAQ blog explains equals better:
The Equals method is just a virtual
one defined in System.Object, and
overridden by whichever classes choose
to do so. The == operator is an
operator which can be overloaded by
classes, but which usually has
identity behaviour.
For reference types where == has not
been overloaded, it compares whether
two references refer to the same
object - which is exactly what the
implementation of Equals does in
System.Object.

What is the difference between .Equals and == [duplicate]

This question already has answers here:
C# difference between == and Equals()
(20 answers)
Closed 9 years ago.
What is the difference between a.Equals(b) and a == b for value types, reference types, and strings? It would seem as though a == b works just fine for strings, but I'm trying to be sure to use good coding practices.
From When should I use Equals and when should I use ==:
The Equals method is just a virtual
one defined in System.Object, and
overridden by whichever classes choose
to do so. The == operator is an
operator which can be overloaded by
classes, but which usually has
identity behaviour.
For reference types where == has not
been overloaded, it compares whether
two references refer to the same
object - which is exactly what the
implementation of Equals does in
System.Object.
Value types do not provide an overload
for == by default. However, most of
the value types provided by the
framework provide their own overload.
The default implementation of Equals
for a value type is provided by
ValueType, and uses reflection to make
the comparison, which makes it
significantly slower than a
type-specific implementation normally
would be. This implementation also
calls Equals on pairs of references
within the two values being compared.
using System;
public class Test
{
static void Main()
{
// Create two equal but distinct strings
string a = new string(new char[] {'h', 'e', 'l', 'l', 'o'});
string b = new string(new char[] {'h', 'e', 'l', 'l', 'o'});
Console.WriteLine (a==b);
Console.WriteLine (a.Equals(b));
// Now let's see what happens with the same tests but
// with variables of type object
object c = a;
object d = b;
Console.WriteLine (c==d);
Console.WriteLine (c.Equals(d));
}
}
The result of this short sample program is
True
True
False
True
Here is a great blog post about WHY the implementations are different.
Essentially == is going to be bound at compile time using the types of the variables and .Equals is going to be dynamically bound at runtime.
In the most shorthand answer:
== opertator is to check identity. (i.e: a==b are these two are the same object?)
.Equals() is to check value. (i.e: a.Equals(b) are both holding identical values?)
With one exception:
For string and predefined value types (such as int, float etc..),
the operator == will answer for value and not identity. (same as using .Equals())
One significant difference between them is that == is a static binary operator that works on two instances of a type whereas Equals is an instance method. The reason this matters is that you can do this:
Foo foo = new Foo()
Foo foo2 = null;
foo2 == foo;
But you cannot do this without throwing a NullReferenceException:
Foo foo = new Foo()
Foo foo2 = null;
foo2.Equals(foo);
At a simple level, the difference is which method is called. The == method will attempt ot bind to operator== if defined for the types in question. If no == is found for value types it will do a value comparison and for reference types it will do a reference comparison. A .Equals call will do a virtual dispatch on the .Equals method.
As to what the particular methods do, it's all in the code. Users can define / override these methods and do anything they please. Ideally this methods should be equivalent (sorry for the pun) and have the same output but it is not always the case.
One simple way to help remember the difference is that a.Equals(b) is more analogous to
a == (object)b.
The .Equals() method is not generic and accepts an argument of type "object", and so when comparing to the == operator you have to think about it as if the right-hand operand were cast to object first.
One implication is that a.Equals(b) will nearly always return some value for a and b, regardless of type (the normal way to overload is to just return false if b is an unkown type). a == b will just throw an exception if there's no comparison available for those types.
"==" is an operator that can be overloaded to perform different things based on the types being compared.
The default operation performed by "==" is a.Equals(b);
Here's how you could overload this operator for string types:
public static bool operator == (string str1, string str2)
{
return (str1.Length == str2.Length;)
}
Note that this is different than str1.Equals(str2);
Derived classes can also override and redefine Equals().
As far as "best practices" go, it depends on your intent.
For strings you want to be careful of culture specific comparisons. The classic example is the german double S, that looks a bit like a b. This should match with "ss" but doesn't in a simple == comparison.
For string comparisons that are culture sensitive use: String.Compare(expected, value, StringComparison....) == 0 ? with the StringComparison overload you need.
By default, both == and .Equals() are equivalent apart from the possibility of calling .Equals() on a null instance (which would give you a NullReferenceException). You can, however, override the functionality of either of them independently (though I'm not sure that would ever be a good idea unless you're trying to work around the shortcomings of another system), which would mean you could MAKE them different.
You'll find people on both sides of the aisle as to the one to use. I prefer the operator rather than the function.
If you're talking about strings, though, it's likely a better idea to use string.Compare() instead of either one of those options.

Differences in string compare methods in C#

Comparing string in C# is pretty simple. In fact there are several ways to do it. I have listed some in the block below. What I am curious about are the differences between them and when one should be used over the others? Should one be avoided at all costs? Are there more I haven't listed?
string testString = "Test";
string anotherString = "Another";
if (testString.CompareTo(anotherString) == 0) {}
if (testString.Equals(anotherString)) {}
if (testString == anotherString) {}
(Note: I am looking for equality in this example, not less than or greater than but feel free to comment on that as well)
Here are the rules for how these functions work:
stringValue.CompareTo(otherStringValue)
null comes before a string
it uses CultureInfo.CurrentCulture.CompareInfo.Compare, which means it will use a culture-dependent comparison. This might mean that ß will compare equal to SS in Germany, or similar
stringValue.Equals(otherStringValue)
null is not considered equal to anything
unless you specify a StringComparison option, it will use what looks like a direct ordinal equality check, i.e. ß is not the same as SS, in any language or culture
stringValue == otherStringValue
Is not the same as stringValue.Equals().
The == operator calls the static Equals(string a, string b) method (which in turn goes to an internal EqualsHelper to do the comparison.
Calling .Equals() on a null string gets null reference exception, while on == does not.
Object.ReferenceEquals(stringValue, otherStringValue)
Just checks that references are the same, i.e. it isn't just two strings with the same contents, you're comparing a string object with itself.
Note that with the options above that use method calls, there are overloads with more options to specify how to compare.
My advice if you just want to check for equality is to make up your mind whether you want to use a culture-dependent comparison or not, and then use .CompareTo or .Equals, depending on the choice.
From MSDN:
"The CompareTo method was designed primarily for use in sorting or
alphabetizing operations. It should not be used when the primary
purpose of the method call is to determine whether two strings are
equivalent. To determine whether two strings are equivalent, call
the Equals method."
They suggest using .Equals instead of .CompareTo when looking solely for equality. I am not sure if there is a difference between .Equals and == for the string class. I will sometimes use .Equals or Object.ReferenceEquals instead of == for my own classes in case someone comes along at a later time and redefines the == operator for that class.
If you are ever curious about differences in BCL methods, Reflector is your friend :-)
I follow these guidelines:
Exact match: EDIT: I previously always used == operator on the principle that inside Equals(string, string) the object == operator is used to compare the object references but it seems strA.Equals(strB) is still 1-11% faster overall than string.Equals(strA, strB), strA == strB, and string.CompareOrdinal(strA, strB). I loop tested with a StopWatch on both interned/non-interned string values, with same/different string lengths, and varying sizes (1B to 5MB).
strA.Equals(strB)
Human-readable match (Western cultures, case-insensitive):
string.Compare(strA, strB, StringComparison.OrdinalIgnoreCase) == 0
Human-readable match (All other cultures, insensitive case/accent/kana/etc defined by CultureInfo):
string.Compare(strA, strB, myCultureInfo) == 0
Human-readable match with custom rules (All other cultures):
CompareOptions compareOptions = CompareOptions.IgnoreCase
| CompareOptions.IgnoreWidth
| CompareOptions.IgnoreNonSpace;
string.Compare(strA, strB, CultureInfo.CurrentCulture, compareOptions) == 0
As Ed said, CompareTo is used for sorting.
There is a difference, however, between .Equals and ==.
== resolves to essentially the following code:
if(object.ReferenceEquals(left, null) &&
object.ReferenceEquals(right, null))
return true;
if(object.ReferenceEquals(left, null))
return right.Equals(left);
return left.Equals(right);
The simple reason is the following will throw an exception:
string a = null;
string b = "foo";
bool equal = a.Equals(b);
And the following will not:
string a = null;
string b = "foo";
bool equal = a == b;
Good explanation and practices about string comparison issues may be found in the article New Recommendations for Using Strings in Microsoft .NET 2.0 and also in Best Practices for Using Strings in the .NET Framework.
Each of mentioned method (and other) has particular purpose. The key difference between them is what sort of StringComparison Enumeration they are using by default. There are several options:
CurrentCulture
CurrentCultureIgnoreCase
InvariantCulture
InvariantCultureIgnoreCase
Ordinal
OrdinalIgnoreCase
Each of above comparison type targets different use case:
Ordinal
Case-sensitive internal identifiers
Case-sensitive identifiers in standards like XML and HTTP
Case-sensitive security-related settings
OrdinalIgnoreCase
Case-insensitive internal identifiers
Case-insensitive identifiers in standards like XML and HTTP
File paths (on Microsoft Windows)
Registry keys/values
Environment variables
Resource identifiers (handle names, for example)
Case insensitive security related settings
InvariantCulture or InvariantCultureIgnoreCase
Some persisted linguistically-relevant data
Display of linguistic data requiring a fixed sort order
CurrentCulture or CurrentCultureIgnoreCase
Data displayed to the user
Most user input
Note, that StringComparison Enumeration as well as overloads for string comparison methods, exists since .NET 2.0.
String.CompareTo Method (String)
Is in fact type safe implementation of IComparable.CompareTo Method. Default interpretation: CurrentCulture.
Usage:
The CompareTo method was designed primarily for use in sorting or alphabetizing operations
Thus
Implementing the IComparable interface will necessarily use this method
String.Compare Method
A static member of String Class which has many overloads. Default interpretation: CurrentCulture.
Whenever possible, you should call an overload of the Compare method that includes a StringComparison parameter.
String.Equals Method
Overriden from Object class and overloaded for type safety. Default interpretation: Ordinal.
Notice that:
The String class's equality methods include the static Equals, the static operator ==, and the instance method Equals.
StringComparer class
There is also another way to deal with string comparisons especially aims to sorting:
You can use the StringComparer class to create a type-specific comparison to sort the elements in a generic collection. Classes such as Hashtable, Dictionary, SortedList, and SortedList use the StringComparer class for sorting purposes.
Not that performance usually matters with 99% of the times you need to do this, but if you had to do this in a loop several million times I would highly suggest that you use .Equals or == because as soon as it finds a character that doesn't match it throws the whole thing out as false, but if you use the CompareTo it will have to figure out which character is less than the other, leading to slightly worse performance time.
If your app will be running in different countries, I'd recommend that you take a look at the CultureInfo implications and possibly use .Equals. Since I only really write apps for the US (and don't care if it doesn't work properly by someone), I always just use ==.
In the forms you listed here, there's not much difference between the two. CompareTo ends up calling a CompareInfo method that does a comparison using the current culture; Equals is called by the == operator.
If you consider overloads, then things get different. Compare and == can only use the current culture to compare a string. Equals and String.Compare can take a StringComparison enumeration argument that let you specify culture-insensitive or case-insensitive comparisons. Only String.Compare allows you to specify a CultureInfo and perform comparisons using a culture other than the default culture.
Because of its versatility, I find I use String.Compare more than any other comparison method; it lets me specify exactly what I want.
One BIG difference to note is .Equals() will throw an exception if first string is null, Whereas == will not.
string s = null;
string a = "a";
//Throws {"Object reference not set to an instance of an object."}
if (s.Equals(a))
Console.WriteLine("s is equal to a");
//no Exception
if(s==a)
Console.WriteLine("s is equal to a");
s1.CompareTo(s2): Do NOT use if primary purpose is to determine whether two strings are equivalent
s1 == s2: Cannot ignore case
s1.Equals(s2, StringComparison): Throws NullReferenceException if s1 is null
String.Equals(s2, StringComparison): By process of eliminiation, this static method is the WINNER (assuming a typical use case to determine whether two strings are equivalent)!
Using .Equals is also a lot easier to read.
with .Equals, you also gain the StringComparison options. very handy for ignoring case and other things.
btw, this will evaluate to false
string a = "myString";
string b = "myString";
return a==b
Since == compares the values of a and b (which are pointers) this will only evaluate to true if the pointers point to the same object in memory. .Equals dereferences the pointers and compares the values stored at the pointers.
a.Equals(b) would be true here.
and if you change b to:
b = "MYSTRING";
then a.Equals(b) is false, but
a.Equals(b, StringComparison.OrdinalIgnoreCase)
would be true
a.CompareTo(b) calls the string's CompareTo function which compares the values at the pointers and returns <0 if the value stored at a is less than the value stored at b, returns 0 if a.Equals(b) is true, and >0 otherwise. However, this is case sensitive, I think there are possibly options for CompareTo to ignore case and such, but don't have time to look now.
As others have already stated, this would be done for sorting. Comparing for equality in this manner would result in unecessary overhead.
I'm sure I'm leaving stuff out, but I think this should be enough info to start experimenting if you need more details.

Categories