Skip to content

Dynamic dispatch

本文介绍OOP subtyping polymorphism的实现。

Single dispatch and multiple dispatch

关于single dispatch和multiple dispatch的讨论,参见Theory\Programming-paradigm\Abstraction-and-polymorphism\Polymorphism\Implementation章节。

wikipedia Dynamic dispatch

In computer science, dynamic dispatch is the process of selecting which implementation of a polymorphic operation (method or function) to call at run time. It is commonly employed in, and considered a prime characteristic of, object-oriented programming (OOP) languages and systems.[1]

Single and multiple dispatch

Dynamic dispatch mechanisms

NOTE: 描述如何试下dynamic dispatch

wikipedia Multiple dispatch

Multiple dispatch or multimethods is a feature of some programming languages in which a function or method can be dynamically dispatched based on the run time (dynamic) type or, in the more general case, some other attribute of more than one of its arguments.[1] This is a generalization of single dispatch polymorphism where a function or method call is dynamically dispatched based on the derived type of the object on which the method has been called.

Multiple dispatch routes the dynamic dispatch to the implementing function or method using the combined characteristics of one or more arguments.

NOTE:最后一段话是点睛之笔。关于"route"这个词,参见文章Abstract-and-concrete

Examples

Languages with built-in multiple dispatch

C

C# introduced support for dynamic multimethods in version 4[8] (April 2010) using the 'dynamic' keyword.

   class Program
   {
        static void Main(string[] args)
        {
            // Static dispatch to Collider.Collide method
            Console.WriteLine(Collider.Collide(new Asteroid(101), new Spaceship(300)));
            Console.WriteLine(Collider.Collide(new Asteroid(10), new Spaceship(10)));
            Console.WriteLine(Collider.Collide(new Spaceship(101), new Spaceship(10)));
        }
    }

    static class Collider
    {
        public static string Collide(SpaceObject x, SpaceObject y) => (x, y) switch
        {
            _ when x.Size > 100 && y.Size > 100 => "big-boom",
            _ => CollideWith(x as dynamic, y as dynamic)  // Dynamic dispatch to CollideWith method
        };

        // C# does not support global functions.  Class methods are the only way to implement
        // the CollideWith functions.  You could define these as non-private static methods in
        // a separate class and use a 'using static' directive to reference them as if they
        // were global.  This would not require any change to the Collide method above.
        private static string CollideWith(Asteroid x, Asteroid y) => "a/a";
        private static string CollideWith(Asteroid x, Spaceship y) => "a/s";
        private static string CollideWith(Spaceship x, Asteroid y) => "s/a";
        private static string CollideWith(Spaceship x, Spaceship y) => "s/s";
    }

    abstract class SpaceObject
    {
        public SpaceObject(int size)
        {
            Size = size;
        }

        public int Size { get; }
    }

    class Asteroid : SpaceObject
    {
        public Asteroid(int size) : base(size) { }
    }

    class Spaceship : SpaceObject
    {
        public Spaceship(int size) : base(size) { }
    }

Output:

big-boom
a/s
s/s

C++

NOTE: 参见:

1) C++\Language-reference\Classes\Subtype-polymorphism章节

2) C++\Pattern\Visitor-pattern章节

其中收录了: thegreenplace A polyglot's guide to multiple dispatch ,这篇文章非常好。

wikipedia Double dispatch

In software engineering, double dispatch is a special form of multiple dispatch, and a mechanism that dispatches a function call to different concrete functions depending on the runtime types of two objects involved in the call.

TODO

Double Dispatch: the next best thing with respect to Dependency Injection

How does double dispatch work in Visitor pattern?

Double Dispatch is a Code Smell · Los Techies

A polyglot's guide to multiple dispatch