如何根据C#中的参数运行时类型调度方法? 4?

时间:2010-05-12 11:46:44

标签: c# methods dispatch

我有一个对象o,它在运行时保证是三种类型之一ABC,所有这些类型都实现了一个公共接口{{ 1}}。我可以控制I,但不能控制IAB。 (因此我可以使用空标记接口,或者通过使用接口以某种方式利用类型中的相似性,但我无法添加新方法或更改类型中的现有方法。)

我还有一系列方法CMethodAMethodB。查找MethodC的运行时类型,然后将其用作这些方法的参数。

o

现在使用此策略,必须对public void MethodA(A a) { ... } public void MethodB(B b) { ... } public void MethodC(C c) { ... } 的类型执行检查,以确定应调用哪种方法。相反,我想简单地有三个重载方法:

o

现在我让C#执行调度,而不是自己手动执行。可以这样做吗?当然,天真直白的方法不起作用:

  

无法解析方法'Method(object)'。候选人是:

     
      
  • void方法(A)
  •   
  • void方法(B)
  •   
  • void方法(C)
  •   

5 个答案:

答案 0 :(得分:7)

如果你可以重构它,将方法移动到接口并让每个类都有它的实现:

I i = o as I;
i.Method();

答案 1 :(得分:5)

这样的事情怎么样?

private Dictionary<Type, Action<I>> _mapping = new Dictionary<Type, Action<I>>
{ 
  { typeof(A), i => MethodA(i as A)},
  { typeof(B), i => MethodB(i as B)},
  { typeof(C), i => MethodC(i as C)},
};

private void ExecuteBasedOnType(object value)
{
    if(_mapping.ContainsKey(value.GetType()))
       _mapping(value.GetType())(value as I);
}

答案 2 :(得分:0)

如果A类,B类和C类实现接口I,则不应该执行任何操作。运行时为您选择正确的方法:

A a = new A();
class.Method(a); // will calll Method(A a)

B b = new B();
class.Method(b); // will call Method(B b)

答案 3 :(得分:0)

预计O被声明为类型/接口I然后被实例化为b或c。这样做的方法是使用单个公共方法获取类型I的参数,然后在该方法中执行逻辑,例如调用私人方法A B或C.

阅读你编辑过的帖子,o是object类型,记得当你拿到一个对象时要清楚,因为它是一个c#类型,它是一个类实例的通用术语。

你为什么宣称它是一个对象,而不是一个i,以后可能是其他东西?

如果是这样使用重载方法,则必须在调用方法之前将其取消装箱。 e.g。

if (o.GetType() == typeof(a))
{
   oa = (a)o;
   Method(oa);
}
else if(o.GetType() == typeof(b))
{
    ...
}

或者,如果你让方法采用i型的参数,你可以做类似的事情:

i oi = (i)o;
Method(oi);

但您仍需要执行类似公共方法中的第一个示例。

答案 4 :(得分:0)

我不是100%确定这是否适用于您的场景,但听起来您可以使用部分类:

public interface IMethodCallable
{
    public void Method();
}

public partial class A : IMethodCallable
{
    public void Method()
    {
        ....
    }
}

然后用于:

object o = getObject(); // we know this is A, B or C
((IMethodCallable)o).Method();