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

时间:2022-02-17 21:36:26

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.

换句话说,我希望EntryPoint方法(下面)根据模板参数的类型动态调用相应的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 个解决方案

#1


Three options:

  • A series of if/else statements (ugly but simple and easy to understand)
  • 一系列if / else语句(丑陋但简单易懂)

  • Double dispatch with the visitor pattern (can be awkward)
  • 用访客模式双重发送(可能很尴尬)

  • Wait until C# 4 and use dynamic typing (might not be feasible in your case)
  • 等到C#4并使用动态类型(在您的情况下可能不可行)

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.

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

#2


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.

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

#3


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

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

#4


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

我假设您已经考虑使用具有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);
    }
}

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

#1


Three options:

  • A series of if/else statements (ugly but simple and easy to understand)
  • 一系列if / else语句(丑陋但简单易懂)

  • Double dispatch with the visitor pattern (can be awkward)
  • 用访客模式双重发送(可能很尴尬)

  • Wait until C# 4 and use dynamic typing (might not be feasible in your case)
  • 等到C#4并使用动态类型(在您的情况下可能不可行)

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.

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

#2


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.

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

#3


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

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

#4


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

我假设您已经考虑使用具有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);
    }
}

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