473,411 Members | 2,068 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,411 software developers and data experts.

Double Dispatch in C#?

I'd like to find an elegant solution to the problem of calling a
certain function based on the types of two parameters. In my case,
the functions compute the distance between different types of
geometric objects, and I want to call the function that gives me the
most accurate distance.

I have a base class called Shape with basic functionality:

Shape

Then I have the following geometric types derived from Shape (not
always directly). Note I'm simplifying things here, not necessarily
the actual derived types:

Ellipse : Shape;
Circle : Ellipse;
Polyline : Shape;
BezierLine : Polygon;
Text : Shape;

Elsewhere in my code I have an ArrayList of Shapes, and I want to
compute the most accurate distance between any pair of shapes. Let's
say I call a static function called AccurateDistance:

distance = AccurateDistance(shape1, shape2)

I want this to select from a list of static functions that know how to
compute the most accurate distance between any combination of two
shapes:

Distance = Distance(Ellipse shape1, Polyline shape2)
Distance = Distance(Circle shape1, Text shape2)
Distance = Distance(BezierLine shape1, Polyline shape2)

etc ...
I know I could make a big switch statement, or do a bunch of if else
if clauses to dispatch to the best function based on the types of
shape1 and shape2 passed into AccurateDistance. But this seems
tedious and with more shapes added will become very difficult to
maintain. There must be a better solution to this problem. Perhaps
some way of adding the Distance calculation into the Shape classes
themselves? I thought about using delegates, but they need exactly
the same parameters in the param list don't they? Maybe someway of
using reflection?

Any help/ideas is much appreciated,

dan
Nov 16 '05 #1
3 5029
You could use delegates, passing Shape as the parameters. In each of your
methods assigned to the delegate do:

if (param1 is Ellipse && param2 is PolyLine) then
return calculation

so if you were to pass in a circle and a polyline the above code would just
go to the next method assigned to the delegate, if you pass in an ellipse
and polyline then the above code would calc your distance.

Thanks
Wayne

"Dan Vogel" <da*@nonsequitor.com> wrote in message
news:93*************************@posting.google.co m...
I'd like to find an elegant solution to the problem of calling a
certain function based on the types of two parameters. In my case,
the functions compute the distance between different types of
geometric objects, and I want to call the function that gives me the
most accurate distance.

I have a base class called Shape with basic functionality:

Shape

Then I have the following geometric types derived from Shape (not
always directly). Note I'm simplifying things here, not necessarily
the actual derived types:

Ellipse : Shape;
Circle : Ellipse;
Polyline : Shape;
BezierLine : Polygon;
Text : Shape;

Elsewhere in my code I have an ArrayList of Shapes, and I want to
compute the most accurate distance between any pair of shapes. Let's
say I call a static function called AccurateDistance:

distance = AccurateDistance(shape1, shape2)

I want this to select from a list of static functions that know how to
compute the most accurate distance between any combination of two
shapes:

Distance = Distance(Ellipse shape1, Polyline shape2)
Distance = Distance(Circle shape1, Text shape2)
Distance = Distance(BezierLine shape1, Polyline shape2)

etc ...
I know I could make a big switch statement, or do a bunch of if else
if clauses to dispatch to the best function based on the types of
shape1 and shape2 passed into AccurateDistance. But this seems
tedious and with more shapes added will become very difficult to
maintain. There must be a better solution to this problem. Perhaps
some way of adding the Distance calculation into the Shape classes
themselves? I thought about using delegates, but they need exactly
the same parameters in the param list don't they? Maybe someway of
using reflection?

Any help/ideas is much appreciated,

dan

Nov 16 '05 #2
Dan,

I think that you should have some methods on the base Shape class which
are overloaded which help you in the computation. As an example, lets
assume that the distance between two shapes is the distance between their
centers of gravity. Each shape, of course, would have a different center of
gravity.

Assuming each shape knows it's position, the base Shape class could have
a virtual property, CenterOfGravity, which returns a point (based on the
position) that indicates the center of gravity. Then, the static method
would be able to just call the properties to get the center of gravity and
calculate the distance.

The derived classes would then be responsible for providing an override
to indicate the center of gravity.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com
"Dan Vogel" <da*@nonsequitor.com> wrote in message
news:93*************************@posting.google.co m...
I'd like to find an elegant solution to the problem of calling a
certain function based on the types of two parameters. In my case,
the functions compute the distance between different types of
geometric objects, and I want to call the function that gives me the
most accurate distance.

I have a base class called Shape with basic functionality:

Shape

Then I have the following geometric types derived from Shape (not
always directly). Note I'm simplifying things here, not necessarily
the actual derived types:

Ellipse : Shape;
Circle : Ellipse;
Polyline : Shape;
BezierLine : Polygon;
Text : Shape;

Elsewhere in my code I have an ArrayList of Shapes, and I want to
compute the most accurate distance between any pair of shapes. Let's
say I call a static function called AccurateDistance:

distance = AccurateDistance(shape1, shape2)

I want this to select from a list of static functions that know how to
compute the most accurate distance between any combination of two
shapes:

Distance = Distance(Ellipse shape1, Polyline shape2)
Distance = Distance(Circle shape1, Text shape2)
Distance = Distance(BezierLine shape1, Polyline shape2)

etc ...
I know I could make a big switch statement, or do a bunch of if else
if clauses to dispatch to the best function based on the types of
shape1 and shape2 passed into AccurateDistance. But this seems
tedious and with more shapes added will become very difficult to
maintain. There must be a better solution to this problem. Perhaps
some way of adding the Distance calculation into the Shape classes
themselves? I thought about using delegates, but they need exactly
the same parameters in the param list don't they? Maybe someway of
using reflection?

Any help/ideas is much appreciated,

dan

Nov 16 '05 #3
Dan Vogel wrote:
I'd like to find an elegant solution to the problem of calling a
certain function based on the types of two parameters. In my case,
the functions compute the distance between different types of
geometric objects, and I want to call the function that gives me the
most accurate distance.
This sounds like double dispatch, as you mentioned in the header...

I have a base class called Shape with basic functionality:

Shape

Then I have the following geometric types derived from Shape (not
always directly). Note I'm simplifying things here, not necessarily
the actual derived types:

Ellipse : Shape;
Circle : Ellipse;
Polyline : Shape;
BezierLine : Polygon;
Text : Shape;

Elsewhere in my code I have an ArrayList of Shapes, and I want to
compute the most accurate distance between any pair of shapes. Let's
say I call a static function called AccurateDistance:

distance = AccurateDistance(shape1, shape2)

I want this to select from a list of static functions that know how to
compute the most accurate distance between any combination of two
shapes:
Why don't you implement a distanceTo(Shape target) instance method in each
Shape subclass like this (using real double dispatch):

class Circle
{
public float distanceTo(Shape target)
{
// Because we are in an instance of Circle, we know
// we have to calculate the distance to a circle,
// so we dispatch to the appropriate method of the target
return target.distanceToCircle(this);
}

public float distanceToText(Text text)
{
// Calculate the accurate distance between Circle and Text
return distance
}
}

class Text
{
public float distanceTo(Shape target)
{
// Because we are in an instance of Text, we know
// we have to calculate the distance to a text
// so we dispatch to the appropriate method of the target
return target.distanceToText(this);
}

publich float distanceToCircle(Circle circle)
{
// Calculate the accurate distance between Text and Circle
return distance
}
}

and so on.
The distanceToSomething(Something something) methods might be implemented in
the Shape class...

Distance = Distance(Ellipse shape1, Polyline shape2)
Distance = Distance(Circle shape1, Text shape2)
Distance = Distance(BezierLine shape1, Polyline shape2)

etc ...
I know I could make a big switch statement, or do a bunch of if else
if clauses to dispatch to the best function based on the types of
shape1 and shape2 passed into AccurateDistance. But this seems
tedious and with more shapes added will become very difficult to
maintain. There must be a better solution to this problem. Perhaps
some way of adding the Distance calculation into the Shape classes
themselves? I thought about using delegates, but they need exactly
the same parameters in the param list don't they? Maybe someway of
using reflection?

Any help/ideas is much appreciated,

dan

Nov 16 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: RJ | last post by:
Hi, I've been going over the Quick Start to Client side COM and Python and many other sources, but cannot find an example that will get my com/ActiveX .ocx USB device driver imported. The Excel...
13
by: Shea Martin | last post by:
Any one have a better/simpler method for rounding a float to the nearest 1/10th? This is currently what I am using, and there must be a better way, or perhaps a canned method that I am not aware...
1
by: Thomas Matthews | last post by:
Hi, I'm looking for an efficient method to deep copy containers of fields. A Field is a parent class with children such as Integer_Field, String_Field, and Date_Field, etc. The algorithm /...
5
by: markww | last post by:
Hi, Can someone explain to me what static and dynamic dispatch are and what the difference is between the two? Do this even occurr in C++? Thanks
3
by: Tigera | last post by:
Greetings, I too have succumbed to the perhaps foolish urge to write a video game, and I have been struggling with the implementation of multiple dispatch. I read through "More Effective C++"...
0
by: learning | last post by:
hi, is there a way to make a function dispatch table in C#? Purpose: I have am using Microsoft web test to automate web testing. the web test generated are all a collection declarative...
2
by: DeMarcus | last post by:
Since I started with OO I've been told switching on typeid is a big no-no. E.g. void Washer::wash( Vehicle myVehicle ) { if( typeid(myVehicle) == typeid(Car) ) Washer::washCar( myVehicle );...
6
by: saneman | last post by:
I am trying to use double dispatch in the below code: #include <iostream> class Box; class Sphere; class geometry_type {
24
by: Angelo Chen | last post by:
hi, any quick way to check if a double is an odd number or not? thanks
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.