Single / double dispatch via "dynamic overload" in C #

Why is double dispatch via "dynamic overload" based on argument type not supported in C #? I see that this will require dynamic dispatch, but since calls to virtual methods are also sent dynamically, this would not be so strange for the language. So why is this function not part of C #? What would be the most elegant solution to implement this function using Reflection (maybe there are some libraries)?

class Program { static void Main(string[] args) { var objs = new object[] { new Class1(), new Class2() }; foreach (var item in objs) { Method(item); } } static void Method(Class1 obj) { } static void Method(Class2 obj) { } } class Class1 { } class Class2 { } 

UPDATE , because the Method in this example is not virtual and takes only one argument, it will still be one dispatch, but the โ€œpowerโ€ of the dispatch is not as important in this matter as it is longer> 0.

+5
source share
3 answers

virtual intended for separate sending. If you need double dispatch, you can do it in C #:

 var objs = new object[] { new Class1(), new Class2() }; foreach (var item in objs) { Method((dynamic)item); } 

This will make the compiler interpret the call to your method in a completely different way. It will call the so-called call site, which will determine at runtime which method to call. This is also called late binding.

In this particular example, you still get a separate dispatch, but that would be a double dispatch if Method were virtual.

This is very convenient for quick implementation of the visitor template, but keep in mind that this will be slower than classic manual double sending. This way you can use the good old way in performance-sensitive code.

+9
source

Why is double dispatch via "dynamic overload" based on argument type not supported in C #?

Via dynamic tuning :

 static void Main(string[] args) { var objs = new object[] { new Class1(), new Class2() }; // Note the change of type for item to "dynamic" foreach (dynamic item in objs) { Method(item); } } 

Operations using a value with the dynamic compilation time type are associated with a late expiration date, so overload resolution is performed at run time based on the actual value type. Of course, there is much more dynamic input than just overload resolution, including types that members can dynamically provide through code.

Everyone has a performance, but sometimes this is the cleanest approach.

You can add an extra overload with a parameter of type object as "catch-all" if the value does not match any of the other overloads ... although it would still be ambiguous if your array contains a null element.

+4
source

If you're really interested, Andrew Kennedy, one of the .Net CLR generics developers, wrote an article about this.

http://research.microsoft.com/pubs/64039/transposingftocsharp.pdf

Since F #, which has a true parameterized polymorphism, uses the same Common Language runtime, C # supposedly could also implement it, and the solution was one way to preserve the C ++ / C # language.

From his article: โ€œSimilarly, the implementation of polymorphic virtual CLR methods [10] involves the creation of a run-time code, as opposed to generating a loading time code sufficient to support non-virtual polymorphic methods.โ€

+3
source

Source: https://habr.com/ru/post/1203820/


All Articles