2

鉴于:

interface I
{
}

class B: I
{
}

class C: I
{
}

class A
{

    public void Method(B arg)
    {
    }

    public void Method(C arg)
    {
    }

    public void Method(I arg)
    {
       // THIS is the method I want to simplify.
       if (I is B)
       {
          this.Method(arg as B);
       }
       else if (I is C)
       {
          this.Method(arg as C);
       }
    }
}

我知道有更好的方法来设计这种类型的交互,但由于细节需要太长时间来解释,这是不可能的。由于这种模式会被重复很多次,我想用一个我可以只使用一行的通用实现来替换条件逻辑。我看不到实现这个通用方法/类的简单方法,但我的直觉告诉我它应该是可能的。

任何帮助,将不胜感激。

4

6 回答 6

16

我会将方法放在接口中,然后让多态性决定调用哪个方法

interface I
{
   void Method();
}

class B : I
{
   public void Method() { /* previously A.Method(B) */}
}

class C : I
{
   public void Method() { /* previously A.Method(C) */ }
}

class A
{
   public void Method(I obj)
   { 
     obj.Method();
   }
}

现在当你需要添加一个新类时,你只需要实现I.Method。您无需触摸 A.Method。

于 2008-10-06T04:02:06.903 回答
5

您想要的是双重调度,尤其是访问者模式

于 2008-10-06T06:57:27.047 回答
1

这有点难看,但它完成了工作:

public void Method(B arg)
{
  if (arg == null) return;
...
}
public void Method(C arg)
{
  if (arg == null) return;
...
}

public void Method(I arg)
{
  this.Method(arg as B);
  this.Method(arg as C);
}

不过,我不认为我会这样做。看着真的很心疼。对不起,我强迫大家也看看这个。

于 2008-10-06T05:26:33.300 回答
1
interface I
{ 
} 

class B : I
{
}

class C : I
{
}    

class A 
{
    public void Method(B arg)
    {
        Console.WriteLine("I'm in B");
    }

    public void Method(C arg)
    {
        Console.WriteLine("I'm in C");
    }

    public void Method(I arg)
    {
        Type type = arg.GetType();

        MethodInfo method = typeof(A).GetMethod("Method", new Type[] { type });
        method.Invoke(this, new I[] { arg });
    }
}
于 2008-10-06T22:11:33.117 回答
0

它不以 C# 的方便形式存在 -请参阅此处了解基于 F# 模式匹配的想法,这正是您想要的。您可以通过反射做一些事情来在运行时选择重载,但这会非常慢,并且如果有任何东西同时满足这两个重载,则会出现严重问题。如果您有返回值,则可以使用条件运算符;

return (I is B) ? Method((B)I) : ((I is C) ? Method((C)I) : 0);

再次 - 不漂亮。

于 2008-10-06T04:01:20.243 回答
0

简单的。在 Visual Basic 中,我一直使用 CallByName 来执行此操作。

Sub MethodBase(value as Object)
    CallByName(Me, "RealMethod", CallType.Method, value)

这将调用与值的运行时类型最匹配的 RealMethod 的重载。

我相信您可以通过导入 Microsoft.VisualBasic.Interaction 或使用反射创建您自己的版本来使用 C# 中的 CallByName。

于 2008-10-06T05:28:41.860 回答