title: Equality check and downcasting code smell in C#
body: <p>I have a base abstract class <code>Shape</code> with three derived classes: <code>Arc</code>, <code>Circle</code>, <code>Rectangle</code>.</p>
  
  <p>I have equality check in the classes and since Arcs can sometimes have the shape of a complete Circle, I want to consider them also equal! To do that, I check for the type of the shape, downcast and then do the other checks to see if the two shapes are actually representing the same geometry. My problem is here with down-casting. </p>
  
  <p>Isn't it a code smell? How can I do this the right way.</p>
  
  <p>For example, let's say in the future someone inherits from Shape and creates a class that can have similar shape to an Arc as well! Since I have not considered it in the condition of the equality check I will have problems!</p>
  
  <pre><code>public abstract class Shape : IEquatable&lt;Shape&gt;
  {
      public abstract bool Equals(Shape other);
  }
  
  public class Arc : Shape
  {
      public override bool Equals(Shape other)
      {            
          if (other is Arc || other is Circle)
          {
              // Downcast and check for equality criteria!!
          }
          else
          {
              return false;
          }
      }
  }
  
  public class Circle : Shape
  {
      public override bool Equals(Shape other)
      {
          if (other is Arc || other is Circle)
          {
              // Downcast and check for equality criteria!!
          }
          else
          {
              return false;
          }
      }
  }
  
  public class Rectangle : Shape
  {
      public override bool Equals(Shape other)
      {
          if (other is Rectangle)
          {
              // Downcast and check for equality criteria!!
          }
          else
          {
              return false;
          }
      }
  }
  </code></pre>
  
  <p><strong>UPDATE:</strong></p>
  
  <p>After reading the answers and thinking a bit further I believe I need to change my design like this:</p>
  
  <p>Shape class should have a methods like IsEqualToCircle(Circle circle) and IsEqualToCircle(Arc arc).</p>
  
  <p>Then in the equality of Arc class I can write: <code>if(shape.IsEqualToArc(this) return true;</code>) and so on.</p>
  
  <p>The example shown here is just a simplification to show a problem that arises for me in so many situations. Of course, this is not a real code.</p>