代码之家  ›  专栏  ›  技术社区  ›  Arseni Mourzenko

如何在一个带有被动重载的大方法和一堆小重载之间进行选择,每个重载只做少量的工作?

  •  7
  • Arseni Mourzenko  · 技术社区  · 14 年前

    较长的方法体 难以导航 了解哪个超负荷起什么作用。

    例如,如果一个类的两个重载 Cat

    public Cat(string name, int? weight, Color mainColor);
    public Cat(string name);
    

    有两种实现方法:

    第一类

    public Cat(string name, int? weight, Color mainColor)
    {
        // Initialize everything.
        this.name = name;
        if (weight.HasValue) this.weight = weight.Value;
    
        // There is a bug here (see the anwer of @Timwi): mainColor can be null.
        this.colors = new List<Colors>(new[] { mainColor });
    }
    
    public Cat(string name)
        : this(name, null, null)
    {
        // Nothing else to do: everything is done in the overload.
    }
    

    第二类

    public Cat(string name)
    {
        // Initialize the minimum.
        this.name = name;
        this.colors = new List<Colors>();
    }
    
    public Cat(string name, int? weight, Color mainColor)
        : this(name)
    {
        // Do the remaining work, not done in the overload.
        if (weight.HasValue) this.weight = weight.Value;
        this.colors.Add(mainColor);
    }
    

    问题

    1. (能够在网上或书本上查找更多信息)?
    2. 有什么问题吗 在选择这些类型时?

    注意:由于C#4.0允许您指定可选参数,为了避免歧义,假设我只谈论C#3.0。

    2 回复  |  直到 14 年前
        1
  •  3
  •   Timwi    14 年前

    我认为这是另一个例子

    其中一个因素是,第一个有很多如果。您的代码也有一个bug:您将添加一个 null 颜色列表中的值;为了修复该错误,您需要更多的if。这样的构造函数很容易变得混乱。无数的ifs表明,有几种情况下的逻辑是本质上不同的,因此为每种情况使用单独的构造函数是非常有意义的。

    然而,在没有那么多ifs的情况下,逻辑对于所有的ifs都是相同的,所以现在调用一个单独的构造函数来完成这个逻辑是有意义的,而且做得很好。那么只有一个地方可以维护它。

    另一个因素是在你的例子中,第一个离开了 weight 未初始化。 这不一定是坏事 重量 将它初始化为非零的值,只有一些构造函数用另一个值覆盖默认值。构造函数参数和/或 this(...) 调用是记录该字段默认值的更好位置。(最好是构造函数参数,因为 即使是客户端程序员也可以看到默认值 全部的

    所以是的,就像你说的,你不希望方法体太长,但是你也不希望代码太难导航,所以你需要在任何给定的情况下在两者之间取得平衡。

        2
  •  1
  •   Aliostad    14 年前

    第一个

    例如,如果要添加以下内容:

    this.name = name ?? string.Empty;
    

    在第二种情况下,你必须在两个地方做第二个,但在一个地方在第一个。

    同样按照约定,对构造函数进行排序,使其首先以最少的参数开始。