title: Double dispatch inside a single inheritance tree
body: <p>I have an inheritance tree of different <code>Line</code>-classes, starting with the abstract <code>Line</code>-class. I want to be able to intersect each line with each other line, and sometimes, I do not know neither of the runtime types, e.g. I'm calling <code>Line.Intersect(Line)</code> (so I need double dispatch). This will always call the most abstract overload of the overriden <code>Intersect</code>-methods, e.g. <code>Circle.Intersect(Line)</code> instead of <code>Circle.Intersect(actualType)</code>. Here's some example code:</p>
  
  <pre><code>class Program
  {
    static void Main(string[] args)
    {
      Line straightLine = new StraightLine();
      Line circle = new Circle();
  
      // Will print: "Circle intersecting a line."
      // But should print: "Circle intersecting a straight line."
      circle.Intersect(straightLine);
  
      Console.ReadLine();
    }
  }
  
  
  abstract class Line
  {
    public abstract void Intersect(Line line);
  
    public abstract void Intersect(StraightLine straightLine);
  
    public abstract void Intersect(Circle circle);
  }
  
  
  class StraightLine : Line
  {
    public override void Intersect(Line line)
    {
      Console.WriteLine("Straigth line intersecting a line.");
    }
  
    public override void Intersect(StraightLine straightLine)
    {
      Console.WriteLine("Straight line intersecting a straight line.");
    }
  
    public override void Intersect(Circle circle)
    {
      Console.WriteLine("Straight line intersecting a circle.");
    }
  }
  
  
  class Circle : Line
  {
    public override void Intersect(Line line)
    {
      Console.WriteLine("Circle intersecting a line.");
    }
  
    public override void Intersect(Circle circle)
    {
      Console.WriteLine("Circle intersecting a circle.");
    }
  
    public override void Intersect(StraightLine straightLine)
    {
      Console.WriteLine("Circle intersecting a straight line.");
    }
  }
  </code></pre>
  
  <p>One possible workaround is to use <code>dynamic</code>, which I currently do. However, I want to migrate to a .NET Standard-library, where <code>dynamic</code> is not allowed.</p>
  
  <p>Are there other ways to make this work? I'd be willing to switch the abstract class for one or multiple interfaces, if that helps. Maybe the visitor-pattern is applicable, although I've only seen this used for different inheritance trees (and find it quite ugly).</p>