reidLinden
reidLinden

Reputation: 4170

Polymorphism at runtime

I am working on a webapi application with some basic inheritance and polymorphism aspects to a few of the data models. One endpoint in particular is expected to receive and operate on any derived type of an abstract class. With the aid of some JsonCreationConverter code, I can step into my code and see the proper derived type has been selected for my payload.

Things break however, when I then attempt to call a method with overrides for the specific derived types. The compiler complains that it cannot convert from the abstract type to one of the derived types.

My guess is that this sort of polymorphism isn't allowed at runtime, or that I need to set things up differently to make it happen.

Here's a fiddle that describes the basic behavior I'm seeing [ https://dotnetfiddle.net/9BkSP8 ]. Of particular concern is the webApiControllerAction2 method which has the code I'm hoping for.

While webApiControllerAction1 is technically functional, it is not able to remain agnostic about Shapes derived types, and that's the bit I'm hoping to find an answer to.

Edit

Hmm.. my fiddle link isn't showing the most recent version of this that I programmed. I'll have to figure that out... ok... its now showing the correct version, how odd..

Upvotes: 0

Views: 107

Answers (2)

Igor
Igor

Reputation: 62238

That is not polymorphism. Here is an example of that using a method named PrintArea.

The result is that the behavior of the method varies depending on the implementer BUT the caller does not have to know the concrete type of the instance being utilized. In this case there is a list of shapes and the caller can call PrintArea but is unaware of how that method is implemented and of the type that implements the method.

From Wiki

In programming languages and type theory, polymorphism (from Greek πολύς, polys, "many, much" and morphē, "form, shape") is the provision of a single interface to entities of different types.

using System;

namespace TestCode
{
    public abstract class Shape
    {
        public abstract void PrintArea();
    }

    public class Circle : Shape
    {
        public override void PrintArea()
        {
            Console.WriteLine("πr2");
        }
    }

    public class Square : Shape
    {
        public override void PrintArea()
        {
            Console.WriteLine("l*w");
        }
    }

    public class Program
    {
        public static void Main()
        {
            Console.WriteLine("Start");
            var lst = new System.Collections.Generic.List<Shape>();
            lst.Add(new Circle());
            lst.Add(new Square());


            ShowFormula(lst);
        }

        public static void ShowFormula(System.Collections.Generic.IEnumerable<Shape> shapes){
            foreach (var shape in shapes)
              shape.PrintArea();
        }
    }
}

Working fiddle

Upvotes: 1

Mark Larter
Mark Larter

Reputation: 2363

Took your fiddle and roughed-in the missing polymorphism:

using System;

public abstract class Shape {
    public string shapeType {get; set;}
    public abstract double Area { get; }
}

public class Circle : Shape
{
    public int radius {get; set;}
    public override double Area { get { return 3.1415 * radius * radius;} }
}

public class Square : Shape
{
    public int length {get; set;}
    public override double Area { get { return length * length;} }
}

public class Program
{
    public static void Main()
    {
        Console.WriteLine("Hello World {0}" , "foo");
        var circle = new Circle() {shapeType= "Circle", radius = 5};
        var square = new Square() {shapeType= "Square",length = 5};

        webApiControllerAction(circle);
        webApiControllerAction(square);
    }

    public static void webApiControllerAction(Shape shape)
    {
        // just call the appropriate printArea for the derived type
        printArea(shape);
    }

    public static void printArea(Shape s) {
        Console.WriteLine("{0} area = {1}", s.GetType().Name ,s.Area.ToString());
    }
}

Upvotes: 3

Related Questions