【问题标题】:C# Automatically pick most related method for argumentsC#自动为参数选择最相关的方法
【发布时间】:2015-04-20 05:20:47
【问题描述】:

我在 C# 中有以下代码:

static void Main(string[] args)
{
    Object rect = new Rectangle();
    Object circle = new Circle();
    Console.WriteLine(count(rect, circle));
}

public static int count(Object obj1, Object obj2)
{
    return 4;
}

public static int count(Rectangle rect, Circle circ)
{
   return 0;
}

程序输出 4,但是,我希望它选择更适合这种情况的方法,这将是第二种方法。我不能简单地将变量 rect 和 circle 定义为它们的特定类型,因为在我的代码上下文中,我不知道它们的类型是什么。

我尝试实现这一点的方式是否完全错误,或者是否有一种相当简单的方法可以自动选择正确的方法?

【问题讨论】:

  • 可悲的是编译器选择了正确的方法,编译器看到的是Object和Object,而不是Rectangle和Circle
  • 是的,但是由于 Rectangle 和 Circle 是更适合第二种方法的参数的子类,编译器应该选择第二种方法吗?
  • 您在这里处理的概念是动态分派或多分派,这类似于方法重载,但在运行时而不是在编译时选择方法。这里是a related question
  • @DanDoe 不,C# 编译器不执行您的程序,因此它看不到rectcircle 中可能存在的值。它只能看rectcircle的类型,因为它们是“确定”的东西

标签: c# methods overloading


【解决方案1】:

如果你真的想在运行时选择方法,你可以使用dynamic。请注意,它是

dynamic rect = new Rectangle();
dynamic circle = new Circle();
Console.WriteLine(count(rect, circle));

而且我仍然觉得你应该使用的模式是不同的,但是除非你告诉我们你真正想要什么,否则很难解释什么应该是真正的模式。

例如不使用动态你可以:

public static int count(Object obj1, Object obj2)
{
    if (obj1 is Rectangle && obj2 is Circle)
    {
        return count((Rectangle)obj1, (Circle)obj2);
    }

    return 4;
}

请注意,我仍然觉得这里有问题,因为如果您这样做会发生什么

Console.WriteLine(count(circle, rect));

(我反转了circlerect)。你想要相同的结果还是不同的结果?在这两种情况下,您也必须处理这种情况!

其他问题:您必须处理的案件数量呈指数级增长。 2个数字,你有4个案例(rect + rect,circle + circle,rect + circle,circle + rect),但是4个数字你已经有16个案例,6个数字36个案例......

【讨论】:

    【解决方案2】:

    您需要使用 dynamic 关键字在代码中触发动态调度(运行时评估):

    static void Main(string[] args)
    {
        Object rect = new Rectangle();
        Object circle = new Circle();
        Console.WriteLine(count((dynamic) rect, (dynamic) circle));
    }
    

    在您的示例中,这将打印 0 而不是 4。

    【讨论】:

      猜你喜欢
      • 2013-11-09
      • 1970-01-01
      • 1970-01-01
      • 2014-04-01
      • 2015-01-06
      • 2023-03-05
      • 2022-11-24
      • 2011-10-18
      • 1970-01-01
      相关资源
      最近更新 更多