Wednesday, May 27, 2015

dynamic dispatch using "as dynamic" in c#

I found a new entry for our internal coding guidelines: "don't use dynamic dispatching if not absolutely necessary!".

wikipedia:
...
In computer sciencedynamic dispatch is the process of selecting which implementation of a polymorphic operation (method or function) to call at run time. Dynamic dispatch contrasts with static dispatch in which the implementation of a polymorphic operation is selected at compile-time. The purpose of dynamic dispatch is to support cases where the appropriate implementation of a polymorphic operation can't be determined at compile time because it depends on the runtime type of one or more actual parameters to the operation.
...
Dynamic dispatch is often used in object-oriented languages when different classes contain different implementations of the same method due to common inheritance. 
...


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Dynamic
{
    public interface IInt
    {
    }

    public class A : IInt
    {
    }

    public class B : A
    {

    }

    class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();

            IInt x = new A();
            p.Print(x);
            p.Print((A)x);
            p.Print(x as B);
            p.Print(123);
            p.Print(x as dynamic);

            Debugger.Break();
        }

        public void Print(IInt p)
        {
            Console.WriteLine("IInt");
            //if (p is B)
            //{
            //    Print(p as B);
            //} 
            //else if(p is A)
            //{
            //    Print(p as A);
            //}
        }

        public void Print(A p)
        {
            Console.WriteLine("A");
        }

        public void Print(B p)
        {
            Console.WriteLine("B");
        }
        /*
        public void Print(object p)
        {
            Console.WriteLine("obj");
        }*/

        public void Print(dynamic p)
        {
            Console.WriteLine("dynamic");
        }
    }
}

Output:
 IInt
A
B
dynamic
A

 The reason why line 61 to 65 is commented out is that it is technically not possible to keep both functions in code ... the one with the object parameter and the one with the dynamic (will be translated to object later). At first sight it seems to be elegant to call line 30 and get the interface function and then call line 34 and get the "right" function, but don't forget the difference... you put compiler decisions to run-time, so you trick the compiler in some ways. Don't do that!

 kind regards,
Daniel

No comments: