1. ## Equals()

Code:
```class TwoDPoint : System.Object
{

public TwoDPoint(int x, int y)  //constructor
{
this.x = x;
this.y = y;
}

public override bool Equals(System.Object obj)
{
// If parameter is null return false.
if (obj == null)
{
return false;
}

// If parameter cannot be cast to Point return false.
TwoDPoint p = obj as TwoDPoint;
if ((System.Object)p == null)
{
return false;
}

// Return true if the fields match:
return (x == p.x) && (y == p.y);
}

public bool Equals(TwoDPoint p)
{
// If parameter is null return false:
if ((object)p == null)
{
return false;
}

// Return true if the fields match:
return (x == p.x) && (y == p.y);
}

public override int GetHashCode()
{
return x ^ y;
}
}```

Code:
```class ThreeDPoint : TwoDPoint
{

public ThreeDPoint(int x, int y, int z)
: base(x, y)
{
this.z = z;
}

public override bool Equals(System.Object obj)
{
// If parameter cannot be cast to ThreeDPoint return false:
ThreeDPoint p = obj as ThreeDPoint;
if ((object)p == null)
{
return false;
}

// Return true if the fields match:
return base.Equals(obj) && z == p.z;
}

public bool Equals(ThreeDPoint p)
{
// Return true if the fields match:
return base.Equals((TwoDPoint)p) && z == p.z;    }

public override int GetHashCode()
{
return base.GetHashCode() ^ z;
}
}```
Look at the bold line. How it casts ThreeDPoint class to TwoDPoint? ThreeDPoint class has three fields, while TwoDLine has two.

2. 2d class is the base class, 3d is the derived class with 2d as a base class.

When you create a 3d class object , in fact you pass 2 of the 3 arguments to the constructor of the base class, this is not a one way street, so going back from a 3d object to a 2d object is fine, as long as 3d is derived from 2d ( of course all the properties/methods of the 3d class will not be available to the downcasted object which now is a 2d object ).

Now in the 3d class you can use any of the base class methods that are public.

I would not write the Equals method of the 3d class like that, but that's just something personal I think.

So there's nothing wrong with what the code is doing.

3. Yeah, there is. There is no IS-A relationship between a 2d- and a 3d-point. Deriving one from the other is a mistake.

4. So if 3d was not derived from 2d that downcasting wouldn't work, correct?

5. >So if 3d was not derived from 2d that downcasting wouldn't work, correct?
Ask yourself this: when does a cast work between two independent types?

6. Ask yourself this: when does a cast work between two independent types?
Till now I didn't know it works.

I found this today:
Code:
```public class A
{
public A() { }
}

public class B : A
{
public B() { }
}```
The new class—the derived class—then gains all the non-private data and behavior of the base class in addition to any other data or behaviors it defines for itself. The new class then has two effective types: the type of the new class and the type of the class it inherits.

In the example above, class B is effectively both B and A. When you access a B object, you can use the cast operation to convert it to an A object. The B object is not changed by the cast, but your view of the B object becomes restricted to A's data and behaviors. After casting a B to an A, that A can be cast back to a B. Not all instances of A can be cast to B—just those that are actually instances of B. If you access class B as a B type, you get both the class A and class B data and behaviors. The ability for an object to represent more than one type is called polymorphism. For more information, see Polymorphism (C# Programming Guide). For more information on casting, see Casting (C# Programming Guide).
It brights.