Method resolution when using dynamic and handling of undefined method for specific derived class

90 Views Asked by At

Let's assume the following inheritance graph:

A<-B<-C<-D<-E<-... (the inheritance tree is actually more complex than this example, and it contains hundreds of actual types). I do not own those types and have no control over their implementation

Let's also assume a set of static methods:

Handle(A a), Handle(B b), Handle(C c), Handle(D d) and so on.

My current implementation of Handle(A a) "dispatches" to the desired method by using the dynamic keyword:

public static void Handle(A a)
{
    Handle((dynamic)a);
}

public static void Handle(B b)
{
    //B specific processing
}

//And so on

The host application sends me the objects in a A[], though each object can have a different runtime type. As it stands, I'm not even interested in objects of type A.

I need different Handle methods because the processing the customer wants to perform is different based on the runtime type of the objects.

My implementation works very well as long as I have an Handle method in my code with the corresponding signature for the runtime type of the objects I'm passed in, but as it stands right now, when an object is passed that doesn't have a specific Handle method, the Handle(A a) method is called recursively causing a stack overflow.

I obviously can't define a Handle(X x) method for each of the hundred or so types that I might get passed from the host application, and each subsequent version of that host application's API can define new types.

So my question is how to handle types that do not have a specific Handle method without having to do an endless series of if statements, or even a long switch statement, to filter the objects for which I don't have a handler method?

Is there any way, at runtime, to determine if a Handle method actually exists for the runtime type of the passed in object? Or are there other ways to cleanly handle the "missing" methods?

Any insight/recommendations welcome.

1

There are 1 best solutions below

0
On BEST ANSWER

I don't remember where I got this idea of dispatching within Handle(A a). I recall seeing something like this on some website, but I now realize that it must have applied to a different use case than what I'm trying to achieve.

I solved my problem by simply moving the cast (dynamic)obj outside the "Handling" methods, and back onto the caller:

 Logger.Handle((dynamic)obj);

And in my implementations, the one for the base of the hierarchy is now just an empty method:

 public class Logger
 {
      public static void Handle(A a){}

      public static void Handle(B b)
      {
           //B specific handling
      }

      //All other Handle methods
 }

This solves the problem. If a specific method doesn't exist for a derived type, then the Handle(A a) method is called, doing nothing.