4

Possible Duplicate:
== or .Equals()

I have a String Array and just want to count number of splitted string items in the array.

But I can't decide on which version I want/need/should use:

if(myStringArray.Count.Equals(47))
{
   // Do something.
}

or

if(myStringArray.Count == 47)
{
   // Do something.
}

Could someone please help me understand the difference between the two approaches and why both ones exist?

I've tried both, and both produce the same result.

Community
  • 1
  • 1
Arrow
  • 2,784
  • 8
  • 38
  • 61
  • 3
    I don't like the accepted answer in that duplicate... it misses important differences, like the non-polymorphic nature of operators, including `==` and that `Equals` is part of the `object` contract... –  Jun 02 '12 at 08:03
  • 1
    (FWIW, I *always* -- as in I cannot think of a counter case at the moment -- use `==` over *types for which it is [well-]defined*: this includes all the standard structure types like `int`, and `Guid`. That is, where the type is not used in a polymorphic fashion and defines `==`.) –  Jun 02 '12 at 08:05

3 Answers3

6

The Equals method provides a means for an object type to define "equality" between two instances. With numbers, Equals and == are the same thing, but when you're using object types they're different: Equals compares equality (are the two objects equivalent to each other), and == compares identity (are the two references to the same object). The class author will override Equals and (typically) compare either all of the object's fields with the other object's fields or compare key fields, depending on the class.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • I am not positive about that boxing bit... don't structure types "extend" object? E.g. they should have Equals, GetHashCode, etc, *without* boxing? –  Jun 02 '12 at 08:09
  • 1
    @pst Everything has `Equals` (and 3 others), because everything is `object`, and `object` defines those methods. May I add to the answer, that the `==` operator can be overloaded as well as the `Equals` can be overridden. – SimpleVar Jun 02 '12 at 08:13
  • @YoryeNathan I just don't get where the boxing occurs here... `object boxed = 1` is something I can understand because `Object.ReferenceEquals((object)1, (object)1)` is false. –  Jun 02 '12 at 08:15
  • @pst: You meant `struct` types? Yes, they do. [`Array#Count`](http://msdn.microsoft.com/en-us/library/bb357392) is an `int` (`Int32`), not a structure. *Edit*: Ah, I see what you're saying, [`Int32` **is** a structure type](http://msdn.microsoft.com/en-us/library/system.int32(v=vs.71).aspx). I think boxing *does* occur, because [`Int32#Equals`](http://msdn.microsoft.com/en-us/library/system.int32.equals(v=vs.71)) accepts an `Object`, not an `Int32`, and the boxing chapter of the spec specifically refers to `int i = 123; object o = (object)i;` being a boxing operation. – T.J. Crowder Jun 02 '12 at 08:16
  • @T.J.Crowded Oh, I see! I was meaning/thinking the receiver, not the argument. –  Jun 02 '12 at 08:21
  • @pst `ReferenceEquals` isn't the way to look at boxing and unboxing. Boxing is "zooming into" an object as something that it derives from (e.g Cat can be boxed to Animal, or LivingBeing, or Object, or ICanMeow). Unboxing is taking something that is already "zoomed in", and treat it as a lower-level (hierarchy-wise) object than the "zoomed in" one, assuming that it actually IS that lower-level object to begin with (e.g After boxing Cat to LivingBeing, we can then take the LivingBeing and do `(Cat)myLivingBeing` or `myLivingBeing as Cat` to get a Cat-reference for that object (zoom out)). – SimpleVar Jun 02 '12 at 08:21
  • 1
    @YoryeNathan: No, that's something else entirely. See the link in the answer to what boxing is. – T.J. Crowder Jun 02 '12 at 08:23
  • It's pretty much the same thing, except I was giving examples with reference types, for easier understanding. – SimpleVar Jun 02 '12 at 08:25
  • Actually, `Int32` has two overloads for the public instace method `Equals`. One takes another `Int32`, and one takes an `Object`. So in this case, the first overload is the best match, so no boxing will actually occur. (The first overload is a non-virtual (implicit) implementation of the `IEquatable` interface; the second one is an override of the method ultimately declared in `System.Object`.) – Jeppe Stig Nielsen Jun 02 '12 at 08:35
  • @JeppeStigNielsen: Thanks, I didn't see that one. So no boxing occurs, does it? Removed that bit. – T.J. Crowder Jun 02 '12 at 08:38
  • @YoryeNathan: I don't think it's related at all. – T.J. Crowder Jun 02 '12 at 08:38
  • 1
    @T.J.Crowder: I would clarify that `==` is *intended* to compare identity. For reference types, this means either reference equality, or possibly equivalence when the type is immutable (such as string). Notwithstanding, it *is* allowed (albeit discouraged) for `==` to be implemented for mutable reference types by custom classes. – Douglas Jun 02 '12 at 08:56
  • If the authors of the struct hadn't cared to make that extra overload of the instance method `Equals`, boxing **would** have occurred. Also if you use the static version of `Equals`, like `Equals(count, 47)`, boxing **will** occur (for both `count` and `47`). – Jeppe Stig Nielsen Jun 02 '12 at 09:20
  • @Douglas Also, it's possible for a type to override `Equals` in one way and define `==` in a different way. But of course, it's strongly recommended to either not change the built-in meaning of `==` **or** make `==` equivalent to `Equals`. – Jeppe Stig Nielsen Jun 02 '12 at 09:29
  • @JeppeStigNielsen: The latter (make `==` equivalent to `Equals`) should *only* be done when the type is immutable. Per [Guidelines for Overriding `Equals()` and Operator `==`](http://msdn.microsoft.com/en-us/library/ms173147.aspx): “By default, the operator `==` tests for reference equality […]. When a type is immutable […], overloading operator `==` to compare value equality instead of reference equality can be useful because, as immutable objects, they can be considered the same as long as they have the same value. Overriding operator `==` in non-immutable types is not recommended.” – Douglas Jun 02 '12 at 10:27
  • @Douglas I agree. In most cases (like mutable reference types) one should not write a user-defined `==` operator. But when it's OK to redefine the `==` operator (like sometimes with immutable structs or classes) **then** you should also override `Equals`, and the two should behave equivalently in that case. – Jeppe Stig Nielsen Jun 02 '12 at 17:31
  • @JeppeStigNielsen: Yes, that I agree with. – Douglas Jun 02 '12 at 17:41
1

In the case of a struct, like the integer used here, there won't be a difference. For classes there could be.

For structs as int,bool,datetime, etc, the intrinsic value is compared with == and not the reference. for classes == compares the reference, but equals can be overridden to apply custom comparisson. for example, if class Foo is a class that contains a primary key, and has overridden it's base equals implementation to compare the keys:

 var foo1 = new Foo{PrimaryKey = 5};
 var foo2 = new Foo{PrimaryKey = 5};
 foo1 == foo2 //false
 foo1.Equals(foo2) //true
Me.Name
  • 12,259
  • 3
  • 31
  • 48
0

Could someone please help me understand the difference between the two approaches

There is no difference in functionality, but the second one is easier to read and understand, so it is preferred.

and why both ones exist?

In C#, System.Int32 is a structure, so it has an Equals(Object) method inherited from System.Object. The .NET developers also added an Equals(Int32) method, which provides an alternative with the same syntax. I have never seen Equals(Int32) used in production code, just because == is easier to read.

Adam Mihalcin
  • 14,242
  • 4
  • 36
  • 52