DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
The Latest "Software Integration: The Intersection of APIs, Microservices, and Cloud-Based Systems" Trend Report
Get the report

Dynamic Overload Resolution

Anders Abel user avatar by
Anders Abel
·
Apr. 10, 12 · Interview
Like (0)
Save
Tweet
Share
4.40K Views

Join the DZone community and get the full member experience.

Join For Free

Both when coding in C++ and C# I’ve had problems with overload resolution being static. There are workarounds, for example the visitor pattern but it requires quite an effort to implement. More importantly it cannot be implemented without changing the visited element. With C#4′s dynamic keyword there is finally a better solution.

To illustrate the problem I’ll implement the ITransportationService interface.

public interface ITransportationService
{
    void TransportAnimal(Animal a);
}

I’ll implement it by delegating the transportation work to the AnimalTransport class. The problem is that AnimalTransport has a special overload for elephants and the ITransportationService.TransportAnimal interface doesn’t.

A Simple Transport

First I’ll show a simple transport, which makes use of the AnimalTransport class.

public static class AnimalTransport
{
    public static void LoadAnimal(Animal animal)
    {
        Debug.WriteLine("Putting " + animal.Name + " in a cage.");
    }
 
    public static void LoadAnimal(Elephant elephant)
    {
        Debug.WriteLine("Loading " + elephant.Name + " on a trailer.");
    }
}
 
public class SimpleTransportation : ITransportationService
{
    public void TransportAnimal(Animal a)
    {
        AnimalTransport.LoadAnimal(a);
    }
}

Executing the code shows a problem.

Transporting an elephant with SimpleTransportation...
Putting Hanibal in a cage.

I think that it might be a problem trying to put Hanibal into an ordinary size pet cage.

A Flexible Transport with Dynamic

Introducing the dynamic keyword handles the situation.

public class FlexibleTransportation : ITransportationService
{
    public void TransportAnimal(Animal a)
    {
        AnimalTransport.LoadAnimal((dynamic)a);
    }
}

Executing the code now loads Hanibal on a trailer instead.

Transporting an elephant with FlexibleTransportation...
Loading Hanibal on a trailer.

Objectoriented Principles

Objectorientation is all about separation of concerns and encapsulation of behaviour. In most cases, it is appropriate to defer to the class itself to decide behaviour that depends on the runtime type. For example, a RunDistance method on the Animal class would be an ordinary virtual (and probably abstract) method, letting each concrete implementation return how fast the specific animal runs.

In this case however I don’t think that it is appropriate. The animal itself should be completely ignorant about how it is transported.
Looking at the AnimalTransport class I think that it is completely reasonable to have a special overload for the elephant. It is huge and requires special handling compared to ordinary animals like cats and dogs.

It is also totally appropriate that the ITransportation interface knows very little about the details of the Animal class hierarchy. Adding a separate overload (if we are at all allowed to change it) there for the elephant would reveal details at the wrong place.
As I mentioned in the beginning of the post the visitor pattern can solve the problem. Unfortunately that requires that the Animal class hierarchy has support for visitors, which is probably not the case if it comes from a library.

I think that using dynamic in this case makes the code clean, elegant and still type safe. If all other classes are already existing and not possible to change, the only other alternative would be manually check the type during runtime.

Visitor pattern ANIMAL (image processing) Interface (computing) Elephant (typeface) Encapsulation (networking) Implementation Trailer (computing) Coding (social sciences)

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Cloud Performance Engineering
  • Building a Real-Time App With Spring Boot, Cassandra, Pulsar, React, and Hilla
  • How To Choose the Right Streaming Database
  • gRPC on the Client Side

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: