2

I have the following code in C#:

static void Main(string[] args)
{
    Object rect = new Rectangle();
    Object circle = new Circle();
    Console.WriteLine(count(rect, circle));
}

public static int count(Object obj1, Object obj2)
{
    return 4;
}

public static int count(Rectangle rect, Circle circ)
{
   return 0;
}

The program outputs 4, however, I'd like it to pick the method that is more specific to this case, which would be the second method. I can't simply define the variables rect and circle as their specific types, because in the context of my code, I don't know what their types are.

Is there something entirely wrong about the way I am trying to implement this, or is there a fairly simple way to automatically choose the correct method?

Dan Doe
  • 1,146
  • 3
  • 14
  • 25
  • 1
    Sadly, it is the compiler that selects the right method, and the compiler sees Object and Object, not Rectangle and Circle – xanatos Apr 20 '15 at 05:22
  • Yes, but surely since Rectangle and Circle are subclasses that fit more correctly into the parameters of the second method, the compiler should select the second method? – Dan Doe Apr 20 '15 at 05:25
  • 2
    The concept you're dealing here is Dynamic Dispatch or Multiple Dispatch, which is similar to method overloading, but where the method is chosen at runtime, rather than at compile-time. Here is [a related question](http://stackoverflow.com/questions/479923/is-c-sharp-a-single-dispatch-or-multiple-dispatch-language) – Avner Shahar-Kashtan Apr 20 '15 at 05:27
  • @DanDoe No, the C# compiler doesn't execute your program, so it can't see what values probably will be present in `rect` and `circle`. It can only look at the types of `rect` and `circle`, because they are something "sure" – xanatos Apr 20 '15 at 05:30

2 Answers2

6

If you really want to select the method at runtime, you can use dynamic. Note that it is slow.

dynamic rect = new Rectangle();
dynamic circle = new Circle();
Console.WriteLine(count(rect, circle));

And I do still feel that the pattern you should use is different, but unless you tell us what you really want, it is difficult to explain what should be the real pattern.

For example without using dynamic you could:

public static int count(Object obj1, Object obj2)
{
    if (obj1 is Rectangle && obj2 is Circle)
    {
        return count((Rectangle)obj1, (Circle)obj2);
    }

    return 4;
}

Note that I still do feel that there is something wrong here, because what happens if you

Console.WriteLine(count(circle, rect));

(I inverted circle and rect). Do you want the same result or different? In both cases, you'll have to handle that case too!

Other problem: there is an exponential growth of the number of cases you have to handle. With 2 figures, you have 4 cases (rect + rect, circle + circle, rect + circle, circle + rect), but with 4 figures you already have 16 cases, with 6 figures 36 cases...

xanatos
  • 109,618
  • 12
  • 197
  • 280
4

You need to trigger dynamic dispatch (runtime evaluation) in your code by using the dynamic keyword:

static void Main(string[] args)
{
    Object rect = new Rectangle();
    Object circle = new Circle();
    Console.WriteLine(count((dynamic) rect, (dynamic) circle));
}

In your example, this will print 0 instead of 4.

jbartuszek
  • 76
  • 4