Search code examples
c#virtualoverriding

Marking ToString virtual in base class, what happens?


Consider the following (LinqPad) example. ToString in class X is marked virtual. Why is the output here not equal to "Hi, I'm Y, Hi, I'm X" but instead the typename is printed? Of course marking ToString virtual is wrong, because it is defined in Object as virtual, I am just trying to understand what is happening here.

void Main()
{
    Y y = new Y();
    Console.WriteLine(y);
}

// Define other methods and classes here

class X
{
  public virtual String ToString() 
  {
    return "Hi, I'm X";
  }
}

class Y : X
{
  public override String ToString() 
  {
    return "Hi, I'm Y, " + base.ToString();
  }
}

Solution

  • That's creating a new virtual method in X called ToString() which hides Object.ToString(). So if you have:

    Y y = new Y();
    X x = y;
    Object o = y;
    
    Console.WriteLine(y.ToString()); // Shows "Hi, I'm Y, Hi, I'm X";
    Console.WriteLine(x.ToString()); // Shows "Hi, I'm Y, Hi, I'm X";
    Console.WriteLine(o.ToString()); // Calls object.ToString; shows just "Y"
    

    Calling just

    Console.WriteLine(y);
    

    is equivalent to the final line, which is why the type name is printed.

    Basically, your X.ToString method should override the object.ToString() method:

    public override String ToString() 
    {
        return "Hi, I'm X";
    }