14

I got bit confused how the following code works

public class DefaultClass
{
    public override bool Equals(object obj)
    {
        return base.Equals(obj);
    }
}

My question is: I am not inheriting any class but how am I still able to override Equals method. This code gets compiled perfectly in VS2010. Any idea how this works?

Peter O.
  • 32,158
  • 14
  • 82
  • 96
DineshKumar
  • 487
  • 3
  • 12
  • 15
    _"if my class doesn't inherit from anything?"_ You are on the wrong track because ([nearly](http://blogs.msdn.com/b/ericlippert/archive/2009/08/06/not-everything-derives-from-object.aspx)) every class inherits from `Object`. – Tim Schmelter Sep 11 '14 at 12:34
  • 4
    @TimSchmelter: Close -- every class *does* inherit from `Object`. Things like interfaces and pointers do not inherit because they are not classes. – Gabe Sep 11 '14 at 12:49
  • 3
    @Gabe: yes, replace class with type and _nearly_ is right. But not only classes derive from object, also value types like `struct` or `enum`. – Tim Schmelter Sep 11 '14 at 13:03
  • @TimSchmelter: Value types are a weird case; according to the ECMA specification, each `Type` other than `System.Enum` which derives from `ValueType` effectively defines two types: one in the universe of storage location types and the other in the universe of heap object types. The storage-location types can implement interfaces as well as methods `Boolean Equals(Object)`, `Int32 HashCode()`, and `String ToString()`, but because they include neither encapsulate nor reference the internal data structures from `Object`, they don't really "inherit" from it. – supercat Sep 11 '14 at 15:48
  • @supercat: [System.Enum is a reference type](http://stackoverflow.com/questions/14561338/enum-is-reference-type-or-value-type). Apart from that you've lost me there. For example, an int's type is System.Int32 which overrides several methods from object like ToString or GetHashCode. – Tim Schmelter Sep 11 '14 at 16:07
  • @TimSchmelter: Perhaps the simplest explanation is to say that a value-type storage locations hold neither an `Object`, nor a reference to one. An object of type `Int32` is an instance of `Object`, but that's not what a storage location of type `Int32` holds. An `Int32` object encapsulates some information related to its type and identity along with its numeric value, but an `Int32` storage location only holds the numeric value and is thus not a complete object. – supercat Sep 11 '14 at 17:07
  • @TimSchmelter: While .NET allows value types to override three methods of `Object`, each override effectively creates two methods--one of which will operate on storage locations of that value type, and the other of which will operate on heap objects of that type. Value-type storage locations only contain the first method, and the corresponding heap-object types only contain the second. – supercat Sep 11 '14 at 17:17
  • Note that if you do override object.Equals you should also override object.GetHashCode. Two objects that are equal must return the same hash code (although objects that are not equal may also return the same hash code). – Russell at ISC Sep 11 '14 at 17:32

5 Answers5

33

Because your DefaultClass 'inherits' from object by default.

You are overriding object.Equals now.

I understand the confusion though. MSDN says that a class like that doesn't inherit any other class, but it does (object):

Inheritance: None. Example: class ClassA { }

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
  • 4
    just want to add for clarity, all types in C# inherits from the father class Object, that is why you can reference all instances of any ref or value to object. – Liran Sep 11 '14 at 12:49
  • 9
    @Liran [Not everything derives from object.](http://blogs.msdn.com/b/ericlippert/archive/2009/08/06/not-everything-derives-from-object.aspx) – Scott Chamberlain Sep 11 '14 at 15:00
  • 1
    According to the ECMA spec, each `Type` other than `Enum` which derives from `ValueType` effectively defines a storage location type and a heap object type. The heap object type derives from `Object`, and the storage location type is convertible to `Object`, but the storage location type doesn't inherit from object in the terminology of the ECMA spec [which among other things implies that if X inherits from Y, a value of type X or a reference to an object of type X must be usable directly as a value of type Y without any representation-changing conversion]. – supercat Sep 11 '14 at 15:54
  • 2
    @ScottChamberlain - The examples Eric Lippert gives are primarily either pointers or "template" types, both of which are understandable; first off, pointers are exposed in C# specifically to make C# code interoperable with unmanaged code in ways that things like marshalling don't cover. They're also highly discouraged in "everyday" C# code. Of more interest to the average C# coder are interfaces and open generics, both of which are basically "templates"; they're not instantiable as such, and so not Objects, but they define rules for the structure of an instance derived from Object. – KeithS Sep 11 '14 at 16:04
  • @KeithS I agree with everything you said but they are still "Types", each one of those things can be expressed as a `System.Type`. So it is still not correct to say "All types derive from `Object`" because there are `Type`s that don't. – Scott Chamberlain Sep 11 '14 at 18:41
  • 3
    @ScottChamberlain: IMHO, the confusion stems from mainly the use of words like "type" to describe several different similar, but distinct, concepts. Given `var l=new List{1,2,3}; var e1=l.GetEnumerator(); IEnumerator e2 = e1;`, both `typeof(e1)` and `e2.GetType()` would yield `List.Enumerator`, but semantically `e1` and `e2` will be very different types: `e1` will be a value type, and `e2` a reference to a heap object. Thus, `e1` will exhibit value-type semantics and `e2` will exhibit class-type semantics. Given that, are `e1` and `e2` really the same "type"? – supercat Sep 11 '14 at 18:55
  • @ScottChamberlain so there are 2 types that does not derives from object, believe me that every developer that uses pointer will know why he cant use equals and such, but developers that ask such a question, wants the simplest answer that wont leave them with more questions, any way thank you for adding your knowledge. – Liran Sep 14 '14 at 10:26
9

Object class is the parent class for all the classes and all classes inherit from it. So your Default Class is also inheriting the Object class

This is the ultimate base class of all classes in the .NET Framework; it is the root of the type hierarchy.

You can understand this using a tree structure:

                     System.Object
                     /           \
                    /             \
                   /               \
SomeProject.DefaultClass        SomeProject.SomeOtherBaseClass
                                         /           \
                                        /             \
                                       /               \
                   SomeProject.ChildClass1       SomeProject.ChildClass2

On a side note also do check this very relevant article by Eric Lippert which may help you in understanding the Object class:- Not everything derives from object

Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
2

System.Object is the ultimate base class of all classes in the .NET Framework; it is the root of the type hierarchy.

Thus all the class can override the method defined in this class. Methods defined in System.Object Class are Equals() ,Finalize() ,GetHashCode() and ToString().

Rajat Srivastava
  • 173
  • 1
  • 1
  • 8
2

Your understanding that you are not inheriting from any class is not right.

See: Object.Equals Method (Object) - MSDN

Because the Object class is the base class for all types in the .NET Framework, the Object.Equals(Object) method provides the default equality comparison for all other types. However, types often override the Equals method to implement value equality.

But, remember to read: Not everything derives from object - Eric Lippert

Habib
  • 219,104
  • 29
  • 407
  • 436
1

Object Class is the base class for all user defined classes , as you are created a class called DefaultClass , this will by sub class for Object class. So the Equals() method is already defined in the Object class hence you are going to overriding this method here.