Elad
Elad

Reputation: 20179

How to call a function dynamically based on an object type

I am looking for an elegant way to call a function based on the type of parameter that is passed as parameter.

In other words, I want the EntryPoint method (below) to dynamically call the appropriate myFunc method, based on the type of the template parameter.

public void EntryPoint(object template)
{
    missingMethod(template);//This is the code in question that should call myFunc
}

private void myFunc(TemplateA template)
{
    doSomething(template);
}

private void myFunc(TemplateB template)
{
    doSomethingElse(template);
}

private void myFunc(object template)
{
    throw new NotImplementedException(template.GetType());
}

Upvotes: 2

Views: 4856

Answers (4)

jerryjvl
jerryjvl

Reputation: 20121

I assume you have considered using an abstract base class that has the myFunc method on it with concrete implementations in the sub-classes?

abstract public class BaseTemplate
{
    abstract protected void MyFunc();
}

public class TemplateA : BaseTemplate
{
    protected override void MyFunc()
    {
        DoSomething(this);
    }
}

public class TemplateB : BaseTemplate
{
    protected override void MyFunc()
    {
        DoSomethingElse(this);
    }
}

Then you'd change your entry point method to:

public void EntryPoint(BaseTemplate template)
{
    template.MyFunc();
}

Or if you want the parameter to stay object:

public void EntryPoint(object template)
{
    BaseTemplate temp = template as BaseTemplate;
    if (temp != null)
        temp.MyFunc();
    else
        throw new NotImplementedException(template.GetType());
}

Upvotes: 0

Eric Schoonover
Eric Schoonover

Reputation: 48392

Here is a quick and dirty solution... should get you going right away.

public void EntryPoint(object template)
{
    TemplateA a = template as TemplateA;
    if (a != null)
    {
        myFunc(a); //calls myFunc(TemplateA template)
        return;
    }

    TemplateB b = template as TemplateB;
    if (b != null)
    {
        myFunc(b); //calls myFunc(TemplateB template)
        return;
    }

    myFunc(template); //calls myFunc(object template)
}

Also, see Jon Skeet's answer for some additional education.

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1499880

Three options:

  • A series of if/else statements (ugly but simple and easy to understand)
  • Double dispatch with the visitor pattern (can be awkward)
  • Wait until C# 4 and use dynamic typing (might not be feasible in your case)

Personally I'd try to think of an alternative design which didn't require this in the first place, but obviously that's not always realistic.

Upvotes: 10

EFraim
EFraim

Reputation: 13028

Why not make myFunc a method? (and override appropriately)

Upvotes: 0

Related Questions