如何基于C#<4中的参数运行时类型调度方法?

Eva*_*ley 5 c# methods dispatch

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

我也有一系列的方法MethodA,MethodBMethodC.o查找运行时类型,然后将其用作这些方法的参数.

public void MethodA(A a) { ... }
public void MethodB(B b) { ... }
public void MethodC(C c) { ... }
Run Code Online (Sandbox Code Playgroud)

使用此策略,现在必须对类型执行检查o以确定应调用哪个方法.相反,我想简单地有三个重载方法:

public void Method(A a) { ... } // these are all overloads of each other
public void Method(B b) { ... }
public void Method(C c) { ... }
Run Code Online (Sandbox Code Playgroud)

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

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

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

Kob*_*obi 7

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

I i = o as I;
i.Method();
Run Code Online (Sandbox Code Playgroud)


Bri*_*sio 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);
}
Run Code Online (Sandbox Code Playgroud)

  • 如果您采用这个建议并使`_mapping`为静态并将`ExecuteBasedOnType`更改为`I`的扩展方法,那么您将获得Kobi建议中的良好语法,而无需重构`A`,`B`和`C` (2认同)