如何根据对象类型动态调用函数

时间:2009-07-26 08:35:02

标签: c#

我正在寻找一种优雅的方法来根据作为参数传递的参数类型来调用函数。

换句话说,我希望EntryPoint方法(下面)根据template参数的类型动态调用相应的myFunc方法。

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());
}

4 个答案:

答案 0 :(得分:9)

三个选项:

  • 一系列if / else语句(丑陋但简单易懂)
  • Double dispatchvisitor pattern(可能很尴尬)
  • 等到C#4并使用动态类型(在您的情况下可能不可行)

就个人而言,我试图想到一个首先不需要这个的替代设计,但显然这并不总是现实的。

答案 1 :(得分:1)

这是一个快速而肮脏的解决方案......应该让你马上去。

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)
}

另外,请参阅Jon Skeet对一些额外教育的回答。

答案 2 :(得分:0)

为什么不让myFunc成为一个方法呢? (并适当覆盖)

答案 3 :(得分:0)

我假设您已经考虑过使用具有myFunc方法的抽象基类,并在子类中使用具体实现?

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);
    }
}

然后您将入口点方法更改为:

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

或者,如果您希望参数保持object

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