5

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

我也有一系列的方法MethodA,,MethodBMethodC。查找运行时类型,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# 进行调度,而不是自己手动进行。这可以做到吗?当然,天真的直接方法不起作用:

无法解析方法“方法(对象)”。候选人是:

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

5 回答 5

7

如果您可以重构它,请将方法移至接口并让每个类都有其实现:

I i = o as I;
i.Method();
于 2010-05-12T11:56:53.857 回答
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);
}
于 2010-05-12T11:56:01.660 回答
0

如果 3 类 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)
于 2010-05-12T11:51:45.180 回答
0

大概 O 被声明为类型/接口,然后实例化为 ab 或 c。这样做的方法是让一个公共方法接受一个类型 I 的参数,然后在该方法中执行你的逻辑,例如调用私有方法 AB 或 C。

阅读您编辑的帖子,o 是对象类型,请记住在使用对象时要清楚,因为它是 ac# 类型,它是类实例的通用 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);

但是您仍然需要在您的公共方法中执行类似于第一个示例的操作。

于 2010-05-12T11:54:47.157 回答
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();
于 2010-05-12T12:10:01.683 回答