Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在一个带有被动重载的大方法和一堆小重载之间进行选择,每个重载只做少量的工作?_C#_.net_Overloading - Fatal编程技术网

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

C# 如何在一个带有被动重载的大方法和一堆小重载之间进行选择,每个重载只做少量的工作?,c#,.net,overloading,C#,.net,Overloading,有两种方法可以实现重载。第一种方法是在一个方法/构造函数中执行所有操作,并从其他重载中调用它,这将导致更长的方法体。第二种方法是在每个重载中执行最小值,因此有时代码很难导航,也很难理解哪个重载做什么 例如,如果类Cat的两个重载为: public Cat(string name, int? weight, Color mainColor); public Cat(string name); 有两种方法可以实现这一点: 第一类 public Cat(字符串名称、整数-权重、颜色主颜色) { //

有两种方法可以实现重载。第一种方法是在一个方法/构造函数中执行所有操作,并从其他重载中调用它,这将导致更长的方法体。第二种方法是在每个重载中执行最小值,因此有时代码很难导航,也很难理解哪个重载做什么

例如,如果类
Cat
的两个重载为:

public Cat(string name, int? weight, Color mainColor);
public Cat(string name);
有两种方法可以实现这一点:

第一类
public Cat(字符串名称、整数-权重、颜色主颜色)
{
//初始化所有内容。
this.name=名称;
如果(weight.HasValue)this.weight=weight.Value;
//这里有一个bug(参见@Timwi的答案):mainColor可以为null。
this.colors=新列表(new[]{mainColor});
}
公共Cat(字符串名称)
:此(名称、null、null)
{
//没有别的事可做:一切都是在超负荷状态下完成的。
}
第二类
public Cat(字符串名称)
{
//初始化最小值。
this.name=名称;
this.colors=新列表();
}
公共Cat(字符串名称、整数-权重、颜色主颜色)
:此(名称)
{
//完成剩余的工作,不要在过载情况下完成。
如果(weight.HasValue)this.weight=weight.Value;
this.colors.Add(mainColor);
}
问题
  • 这两种类型的重载如何被称为(以便能够在互联网或书籍中查找更多信息)
  • 在选择这些类型时,必须考虑哪些主要问题/因素

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

    第一个

    构造函数重载必须始终相互调用或调用公共初始值设定项方法。这是重构和代码模块化的问题,因此您只需进行一次更改

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

    this.name = name ?? string.Empty;
    
    在第二种情况下,你必须在两个地方做第二个,但在第一个地方做一个


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

    我认为这是另一个例子,没有一个单一的、教条式的答案可以合理地涵盖所有情况。我会始终查看个别情况,并根据所有可用的因素做出决定

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

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

    另一个因素是,在您的示例中,第一个未初始化
    weight
    。这不一定是件坏事,因为幸运的是C#中的默认初始化是可预测的;但是如果“代码>权重< /COD>的字段声明将其初始化为非零,并且只有一些构造函数用另一个值覆盖该默认值,那么我会认为这是坏的形式。构造函数参数和/或
    此(…)
    调用是记录该字段默认值的更好地方。(最好是构造函数参数,因为即使客户端程序员也可以看到默认值,但显然这需要C#4。)当然,也可以使用字段初始化器初始化所有字段,并将构造函数保留为空,如果您只有一个没有参数的构造函数,那么这是一个合理的策略


    是的,正如您所说,您不希望方法体太长,但也不希望代码太难导航,因此在任何给定情况下,您都需要在两者之间取得平衡。

    如果您想避免歧义,您必须限制为C#3,而不是.NET Framework 3.x,因为C#4可以针对.NETFramework3.x.@romkyns:note修订版。因此,问题只涉及.NETFramework 3.0(或符合FxCop的.NET4.0解决方案)。C#4编译器可以而且确实编译可选参数,即使是针对.NETFramework 2.0。我现在明白了,您对可选参数不感兴趣,但为什么不直接说呢?为什么你坚持以一种不会阻止你使用可选参数的方式指定框架版本?@romkyns:啊,好的。很抱歉问题编辑。我总是在C#版本和.NET版本之间犯这个错误,因此,再次抱歉。谢谢,我现在更清楚地看到了如何在这两种方法之间进行选择。另外,在我的例子中,
    weight
    字段的类型是
    int
    ,而不是
    int?
    (否则我会直接编写
    this.weight=weight
    )。是的,该字段的默认值应为0。PS:感谢注意,列表中添加了一个带有空值的bug。
    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);
    }
    
    this.name = name ?? string.Empty;