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

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

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

 public void MethodA(A a) { ... } public void MethodB(B b) { ... } public void MethodC(C c) { ... } 

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

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

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

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

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

这样的事怎么样?

 private Dictionary> _mapping = new Dictionary> { { 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); } 

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

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

如果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) 

我不是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(); 

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

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

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

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

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

等等。

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

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

但是你仍然需要像公共方法中的第一个例子那样做。