运行时的多态性

时间:2017-03-08 17:56:23

标签: c#

我正在开发一个webapi应用程序,其中包含一些基本的继承和多态方面,以及一些数据模型。特别是一个端点应该接收和操作任何派生类型的抽象类。借助一些JsonCreationConverter代码,我可以进入我的代码,看到已为我的有效负载选择了正确的派生类型。

然而,当我尝试使用覆盖特定派生类型的方法调用方法时,事情就会中断。编译器抱怨它无法从抽象类型转换为派生类型之一。

我的猜测是,这种多态性在运行时是不允许的,或者我需要以不同的方式设置以实现它。

这是一个描述我看到[https://dotnetfiddle.net/9BkSP8]的基本行为的小提琴。特别值得关注的是webApiControllerAction2方法,它具有我希望的代码。

虽然webApiControllerAction1在技术上有用,但它无法对Shape派生类型保持不可知,而且我希望找到答案。

修改

嗯..我的小提琴链接并没有显示我编程的最新版本。我必须弄清楚......好吧......它现在显示正确的版本,多么奇怪......

2 个答案:

答案 0 :(得分:3)

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());
    }
}

答案 1 :(得分:1)

这不是多态性。以下是使用名为PrintArea的方法的示例。

结果是方法的行为取决于实现者而不同,但是调用者不必知道正在使用的实例的具体类型。在这种情况下,有一个形状列表,调用者可以调用PrintArea但不知道该方法是如何实现的以及实现该方法的类型。

From Wiki

  

在编程语言和类型理论中,多态性(来自希腊语πολύς,polys,“many,much”和morphē,“形式,形状”)是为不同类型的实体提供单一接口。

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