【问题标题】:Best practise: Creating methods, different overloads最佳实践:创建方法、不同的重载
【发布时间】:2013-01-14 23:48:59
【问题描述】:

假设,例如,我们有一个方法,为了论证,我们将其称为 MethodOne;

public void MethodOne()
    {
      //do stuff. 
    }

现在假设我们要创建一个可选参数,并且我们可能决定创建另一个具有相同名称的方法,例如采用不同的重载;

public void MethodOne()
    {
       //do stuff.
    }

public void MethodOne(bool checkVar)
    {
       if(checkVar)
        {
           //do stuff
        }
       else
        {
          //do other stuff
        }
    }

所以现在我们有了一个方法,它有两种不同的重载组合(?)。在实践中,这是否比使用一种方法更好,例如只检查可选重载是否为空或包含信息;

 public void MethodOne(int? testVar)
     {
        if(testVar != null)
         { 
           //do stuff
         }
     }

这对于只有一个重载似乎微不足道,但想象一下我有 5 个要传递的变量,我会创建 5 个方法,不同重载的同名方法,还是只有一个方法并检查传递的变量?

【问题讨论】:

  • 实际上,如果您有五个参数,并且它们都是可选的,那么您最终可能会得到多达 2^5=32 个重载。
  • 这不是重点:P 但是,是的,我明白了。
  • 如果你有一个有五个参数的方法,并且其中任何一个或所有参数都可以为空,你就会遇到不同的问题:你的方法可能做得太多,应该分成更小的方法,每个方法都有一个责任。
  • @Shane.C 这正是重点。如果你需要使用 32 个构造函数重载,那你就做错了 :)
  • 正如 Daniel 指出的那样,您可能需要检查方法的内聚性。你所描述的听起来像是沟通凝聚力:你放在一起的代码是为了对相同的数据进行操作而放在一起的。通常建议争取更高的内聚力,比如功能内聚力,在这种情况下,方法中的所有代码都参与到一个定义明确的任务中。通过努力实现功能内聚,您的耦合应该自然而然地下降(您的参数不会成为太大的问题)

标签: c# methods


【解决方案1】:

有一些解决方法。例如,您可以使用一个枚举器和一个 Object 数组作为包含实际参数值的第二个参数,这样您就可以通过切换枚举器来知道如何处理数据……或者您可以只声明 5 个 Object 参数,然后检查它们的输入一个开关,相应地将它们装箱并继续。但这两种选择都是非常糟糕的做法。

我建议你坚持使用不同的重载:

public void MethodOne(Boolean value)
{
    // Process the value...
}

public void MethodOne(Int32 value)
{
    // Process the value...
}

public void MethodOne(Int32 value, String text)
{
    // Process the value and the text...
}

// And so on...

或参数声明中的默认数据:

public void MethodOne(Int32 integer = 1, String text = "hello", ...)
{
    // Process everything inside the method...
}

或参数化方法(如果每个对象类型都有共同的处理):

public void MethodOne(params Object[] parameters)
{
    for (int i = 0; i < parameters.Length; ++i)
        // Check type of parameter and process the value...
}

或者,如果您的设计允许,方法会冒泡(这是我最喜欢的一种,因为第一种只会产生大量代码冗余,而第二种可能有时会让您或与您一起工作的其他开发人员感到困惑):

public void MethodOne(Int32 value)
{
    MethodOne(value, "hello");
}

public void MethodOne(Int32 value, String text)
{
    // Process everything inside the method...
}

【讨论】:

    【解决方案2】:

    你可以做的是使用optional arguments:

     public void MethodOne(int testVar = 0)
     {
         if(testVar != 0)
         { 
           //do stuff
         }
     }
    

    【讨论】:

    • 我们去吧,把它变成一个“int?”,错过了那个。
    【解决方案3】:

    你通常会在这样的重载上冒泡:

    public void MethodOne()
    {
        MethodOne(1)
    }
    public void MethodOne(int testVar)
    {
        MethodOne(testVar, "test")
    }
    public void MethodOne(int testVar, string testString)
    {
        MethodOne(testVar, testString, null)
    }
    public void MethodOne(int testVar, string testString, object testObject)
    {
        // Do your actual code here
    }
    

    这相当于

    public void MethodOne(int testVar = 1, string testString = "test", object testObject = null)
    {
        // Do your actual code here
    }
    

    但通常你应该避免重载默认参数。此外,通过像我的示例中那样“冒泡”,您可以避免冗余代码或冗余“默认参数”

    【讨论】:

      【解决方案4】:

      随着参数数量的增加,我不想查看方法的嵌套 if/else 逻辑来确定正在使用哪些参数。它很难阅读、理解、维护并且可能导致错误。使用重载并保持方法简洁、精简和可维护。

      【讨论】:

      • +1,点对点。我敢打赌这会是大多数人的想法,尤其是如果你接管了别人的代码。
      猜你喜欢
      • 1970-01-01
      • 2011-02-16
      • 2020-10-08
      • 2011-03-14
      • 1970-01-01
      • 1970-01-01
      • 2014-07-12
      • 1970-01-01
      • 2020-02-28
      相关资源
      最近更新 更多