3

Using the Immediate (or Watch) window in Visual Studio (I'm using VS2015 Community Edition), it's possible to access properties or methods on classes while in break mode. However, for a class derived from another class I can't find a way to access the base class's members if they have been overridden in the derived class, even though this is straightforward to do from code as shown in this example:

public class Program
{
    static void Main(string[] args)
    {
        var ostrich = new Ostrich();
        ostrich.WriteType();
        Console.ReadKey();
    }
}

public class Animal
{
    public void WriteType()
    {
        Console.WriteLine("I'm an {0}", this.Name);
    }

    public virtual string Name => "animal";
}

public class Ostrich : Animal
{
    public override string Name => $"ostrich, not an {base.Name}";
}

If I run this code, the output is (obviously):

I'm an ostrich, not an animal

If I set a breakpoint inside the Name property of the Ostrich class, then check the Name property in the Immediate window, the output is as shown:

?this.Name
"ostrich, not an animal"

If instead I ask for the base class's implementation to be run, I'd expect the output to be "animal". In fact, I get this:

?base.Name
"ostrich, not an animal"

This seems to be not only unhelpful but actually misleading/incorrect: I'd rather an error were returned than the wrong answer.

Using a Watch window, only the derived class's implementation is shown:

Mini-Watch window screenshot

Is there any way to use the Immediate window to access the overridden members of a class's base class?

Neil T
  • 1,794
  • 1
  • 12
  • 21
  • 1
    The only real problem with the expression parser that is used in the Immediate window is that it works too well and creates the illusion that it has the complete C# compiler built-in. It just doesn't, it doesn't know beans about keywords like `base`. Maybe some day it will be updated to use Roslyn, future music. – Hans Passant Mar 06 '17 at 08:50
  • Thanks @Hans, this answer was enlightening for me; I had fallen for exactly the illusion you describe. +1 also for "doesn't know beans". – Neil T Nov 27 '17 at 21:30

1 Answers1

0

I think base. is not publicly available outside the class. If you were writing code outside of the class implementation, to access the property of Animal rather than of Ostrich then you would bracket-cast to Animal.

((Animal)obj).Name

The problem is that even this will still give you ostrich not animal, since this is exactly the behaviour that overriding is supposed to achieve, i.e. that you can access the Name property of an object that you think is of type Animal, but that its functionality can be overridden in a derived class.

I'm not sure of the ins and outs of it from a compiler perspective, but it wouldn't surprise me if the code for the base implementation doesn't even end up in the compiled Ostrich, unless there is code in Ostrich which accesses base.

I agree that the fact that the Immediate window allows you to use base. and then gives you the wrong answer is confusing and likely a bug in Visual Studio, unless others can explain how this makes sense.

It would be interesting to see how the Immediate window behaves if you include some code in Ostrich which accesses base.Name

Jon G
  • 4,083
  • 22
  • 27