繁体   English   中英

为C#中的方法或构造函数提供过多的重载是不好的形式吗?

[英]Is it bad form to provide excessive overloads for a method or constructor in C#?

我正在使用C#为Unity编写代码。 目前,我正在处理一些较小的类和结构,以快速序列化随机生成的地图。 为此,我处理了一些构造函数,这些构造函数也将这些较小的类和结构中的一些作为参数。

过去,在设置方法和构造函数时,我通常会尝试考虑合理的选项 虽然这种做法已被质疑 ,没有人成功地给我任何理由似是而非,为什么我不应该做这样。


考虑以下类和结构:

public class Tile
{
    public GridCoordinates position;
    public TileCode prefabID;
}

public struct GridCoordinates
{
    public int x;
    public int y;
}

public struct TileCode
{
    public int categoryID;
    public int individuaID;
}

通常,在创建构造函数时,我会介绍所有structint替代方法。 Tile看起来像这样:

public class Tile
{
    public GridCoordinates position;
    public TileCode prefabID;

    public Tile(TileCode prefabID, GridCoordinates position)
    {
        this.prefabID = new TileCode(prefabID);
        this.position = new GridCoordinates(position);
    }

    public Tile(TileCode prefabID, int xPosition, int yPosition)
    {
        this.prefabID = new TileCode(prefabID);
        position = new GridCoordinates(xPosition, yPosition);
    }

    public Tile(int typeID, int individualID, GridCoordinates position)
    {
        prefabID = new TileCode(typeID, individualID);
        this.position = new GridCoordinates(position);
    }

    public Tile(int typeID, int individualID, int xPosition, int yPosition)
    {
        prefabID = new TileCode(typeID, individualID);
        position = new GridCoordinates(xPosition, yPosition);
    }

我倾向于这样做是为了提高效率。 与第一个构造函数/方法串联编写其他构造函数/方法时,我花费了很少的时间,当我后来希望以一种本来不是我原来的方式使用构造函数/方法时,我发现这有时会派上用场预期的。

以前提出的唯一问题是混乱的可能性。 我觉得这并不是真正的问题,因为我的组织和评论清楚地区分了每个变体。


最终,我担心我的老师和同龄人可能还没有意识到其他问题。 我目前正在考虑将其扩展到一个更大的项目,现在改变我的行为,比以后纠正它要容易得多。

如果我为类提供过多的替代构造函数或方法,我将面临什么问题?

  • 我不太关心美学和标准问题,尽管可能会提到一个好的答案。 我确实尝试遵循C#标准,但并非总是如此
  • 确实担心这可能带来的潜在资源需求,因此一个好的答案可能会承认那里可能存在的任何问题。
  • 如前所述,我正在为Unity写作。 我知道,尽管大多数C#约定是标准的,但是在Unity中运行时,还是有一些变体。 专门解决此问题的加分点,但通常来说,使用该语言可以解决问题。

只要定义清楚,就可以定义尽可能多的重载,我认为没有错。 我不知道有任何相反推荐的良好做法或原则。 一个明显的缺点显然是代码维护成本的增加。 需要进行更改时进行文档记录和测试。

这使我对您发布的代码产生了极大的抱怨; 我确实在您的代码中感到担忧,而且如果有很多独立的实现,我永远也不会写类似的东西。 如果以后决定更改构造函数逻辑,则必须在整个位置进行更改,这很容易发生错误。 我将重构代码以使用构造函数链接,并在单个重载中实现所有构造逻辑,然后简单地将所有其他构造函数链接/委托给该单个构造函数。

综上所述,我个人的观点是,对于有关您的业务领域的参数应尽可能“强类型化”,您应该尽可能支持重载。 我的意思是:

public Foo(int i, int j, int k, int n) { ... }

容易出错。 Foo(j, i, k, n)的调用是完全有效的,并且一旦出现错误,可能很难在调用堆栈中定位,就很难在大型代码库中定位。

但是类型的签名:

public Foo(Bar bar, Blah blah)

安全得多,因为类型系统和编译器可以为您提供帮助。

您的方法存在的问题是,这违反了“ 不要重复自己做”的原则(也称为“ DRY”)。 添加将参数传递给依赖项的“便捷构造函数”会增加两个模块之间的代码耦合(特别是控制耦合 ),通常应避免这种做法。

但是,在一种情况下,您应该偏爱便捷构造函数:发生在GridCoordinatesTitleCode被视为Title实现详细信息时,因此不应该公开。 在这种情况下,您应该只公开最后一个构造函数,并从类的公共接口中删除所有依赖GridCoordinatesTitleCode构造函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM