Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call Method based on Type of Parameter

Tags:

c#

I have an object that can be of type AudioRequest or VideoRequest. Both classes inherit from Request. I have this class:

public static DoThings
{
    public static void HandleRequest(AudioRequest r)
    {
        // Do things.
    }

    public static void HandleRequest(VideoRequest r)
    {
        // Do things.
    }
}

I want to be able to call DoThings.HandleRequest(r) where r can be either a VideoRequest or AudioRequest and have it call the correct one. Is that possible? I have no control over the *Request classes, so I can't do anything to them. I do have control of the DoThings class and the code that calls HandleRequest. This is the code that calls it, it is WebAPI:

public Response Post(Request input)
{
    return DoThings.HandleRequest(input);
}

The code above gives the error Argument 1: cannot convert from 'Request' to 'AudioRequest'.

The original code that I was cleaning up had this:

if (input.GetType() == typeof(AudioRequest))
{
    var audioRequest = (AudioRequest)input;
    DoThings.HandleRequest(audioRequest);
}
else if (input.GetType() == typeof(VideoRequest))
{
    var videoRequest = (VideoRequest)input;
    DoThings.HandleRequest(videoRequest);
}

But I figured there was a cleaner way to do this.

like image 516
vkapadia Avatar asked Sep 22 '17 05:09

vkapadia


1 Answers

Based on the information you've provided so far, your question appears to be a duplicate of How to call a function dynamically based on an object type. I agree with the answer, that the fact that you want to do this suggests you should rethink the design. But, you can use dynamic to accomplish what you want.

Here's a simple console program that demonstrates the basic idea:

class Program
{
    static void Main(string[] args)
    {
        A b = new B(), c = new C();

        M(b);
        M(c);
    }

    static void M(A a)
    {
        WriteLine("M(A)");
        M((dynamic)a);
    }

    static void M(B b)
    {
        WriteLine("M(B)");
    }

    static void M(C c)
    {
        WriteLine("M(C)");
    }
}

class A { }
class B : A { }
class C : A { }

The output is:

M(A)
M(B)
M(A)
M(C)

As you can see, in each case the M(A) method is called first, and then the appropriate M(B) or M(C) overload is called from M(A).

In your own example, this could look something like this:

public static DoThings
{
    public static void HandleRequest(Request r)
    {
        // Dynamic dispatch to actual method:
        HandleRequest((dynamic)r);
    }

    public static void HandleRequest(AudioRequest r)
    {
        // Do things.
    }

    public static void HandleRequest(VideoRequest r)
    {
        // Do things.
    }
}

Note that dynamic does incur a run-time cost, particularly the first time a method is called with a given run-time type. But depending on the frequency and complexity of these "requests", using dynamic could be the cleanest way out of the current situation.

like image 199
Peter Duniho Avatar answered Sep 28 '22 09:09

Peter Duniho