How does the CLR know which method to call on a derived class inherited from an abstract base?

StackOverflow https://stackoverflow.com/questions/13830202

  •  07-12-2021
  •  | 
  •  

Вопрос

I have the following situation and I was wondering how the CLR knows which method to call:

public abstract class Shape
{
    public abstract String PrintName();
}

public sealed class Square : Shape
{
    public override String PrintName() { return "Square"; }
}

public sealed class Circle : Shape
{
    public override String PrintName() { return "Circle"; }
}

So then I instantiate each shape:

Shape square = new Square();   
Shape circle = new Circle();
List<Shape> shapes = new List<Shape> { square, circle };

foreach (Shape s in shapes)
{
    Console.WriteLine(s.PrintName());   
}

// Output:
// Square
// Circle

So how is it that we can call the method on the derived class even though we are calling the method on the base type? I'm confused how this is handled.

Это было полезно?

Решение 2

When you instantiate Shape square = new Square();, the fact that square really is a Square really is intact. Remember that the variable square really is a reference to the real object. The reference type (in this case, Shape) must be the same class or higher up the inheritance hierachy than the instantiated type (Square), as you have here.

After instantiation, when the compiler sees square, it first knows that it's the abstract type Shape because that's the type of the reference. So, it must be a sub-type of Shape since you can't instantiate an abstract object. Since you said new Square(); the compiler will know the exact type. Again, the exact type of an object is not lost just because you assigned it to a baser (more base) type.

When you call square.PrintName();, the compiler first sees that square is declared with the abstract type Shape, who has a method PrintName(), also marked abstract. This tells the compiler to go look for the same exact method in the child class. If it finds PrintName() in the child class, all is well - the correct function will be executed. If not, you get an error because the word abstract in the base class definition requires you to implement it.

Другие советы

Because of the type safety feature of the CLR, which ensures that when you create an instance of Foo you cannot treat it as Bar, at run time it always knows what type an object is. Therefore when you call PrintName() on your shape it knows if it is dealing with a Square or a Circle.

Note, that as GetType() is non virtual it cannot be overridden and therefore you cannot spoof an object's type.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top