是否重载方法?

时间:2011-02-14 15:00:37

标签: c# class-design

我这里有两个方法(killZombie)来处理你有一个参数(字符串)或多个参数(string [])的情况。因为他们做了同样的事情,我做了另一个名为“killAZombie”的方法,这个方法被其他两种方法使用。我遇到的问题是方法“killAZombie”被命名为......有点奇怪。这是其他人遇到的问题吗?解决这个问题的最佳方法是什么,并将我的“KillAZombie”方法命名为与“killZombie”更明显区分的其他方法

public void killZombie(string zombieLocation){
    killAZombie(zombieLocation);
}

public void killZombie(string[] zombieLocations){
    foreach(string zombieLocation in zombieLocations){
        killAZombie(zombieLocation);
    }
}

public void killAZombie(string zombieLocation){
    //Kills a zombie at specified location
}

我能看到解决这个问题的另一种方法是通过代替重载“killZombie”有两种不同的方法:

public void killZombie(string zombieLocation){
    //Kills a zombie at specified location
}

public void killZombies(string[] zombieLocations){
    foreach(string zombieLocation in zombieLocations){
        killZombie(zombieLocation);
    }
}

这样我们只有两个更容易理解的方法,但是方法没有重载。在我看来,重载方法似乎是一件好事(这只是意味着方法更少,更少杂乱)所以我也不确定这个解决方案。我很想知道解决这个问题的最佳方法,谢谢!

附录:

我的方法实际上需要4个参数,因此参数将在最后。 params变量是最重要的变量,因此将其作为使params工作的最后一个参数似乎有点笨拙。我是否担心将最重要的论点放在最后,足够合法将方法分解为KillZombie和KillZombies,或者params仍然是正确的做法吗?

6 个答案:

答案 0 :(得分:6)

以下是一些想法。

首先,公共方法的C#约定是将它们大写:“KillZombie”,而不是“killZombie”。

如果需要,您只需一种方法就可以完成此操作。这是一个采用一个或多个位置的方法。来电者只需提供一份清单:KillZombies(location1, location2, location3);

private void KillOneZombie(string location) { ... }
public void KillZombies(string location, params string[] additionalLocations)
{
    KillOneZombie(location);
    if (additionalLocations == null) return;
    foreach(string additionalLocation in additionalLocations)
        KillOneZombie(additionalLocation);
}

如果你想要有两种方法,可以考虑让一个方法取一个IEnumerable<string>而不是一个数组;这样调用者可以传入列表,查询,数组等等。

您的第二个命名模式更为标准:KillZombie和KillZombies。

  

params变量是最重要的变量,因此将其作为使params工作的最后一个参数似乎有点笨拙。我是否担心将最重要的论点放在最后,足够合法将方法分解为KillZombie和KillZombies,或者params仍然是正确的做法吗?

我会考虑您希望如何使用该方法。考虑例如:

Console.WriteLine("User: {0} Score: {1}", user[i].Name, scores[i]);

这里我们清楚地期望“params”将用于支持调用者中可变数量的参数。从来没有人这样做过:

object[] results = new object[] { user[i].Name, scores[i] };
Console.WriteLine("User: {0} Score: {1}", results);

即使这是完全合法的。如果您希望您的方法将像Console.WriteLine一样使用,其中将传入不同数量的参数,但参数的数量在编译时是已知的,那么请使用params。

如果您希望它将与第二种模式一起使用 - 某人有一系列位置 - 那么就不要使用params;制作两个方法,KillZombie和KillZombies,并让其中一个采用IEnumerable字符串。

答案 1 :(得分:4)

你的两个选择中的后者可能更好在这种情况下(假设函数的命名意味着它在一个“僵尸”上运行。

但是,您可能还需要查看params关键字,以便了解您的选项。例如,如果你只是简单地命名你的函数Kill(如果在这种情况下这样做是有意义的话),你可以:

public void Kill(params string[] zombieNames)
{
    foreach(string name in zombieNames)
    {

    }
}

你可以通过多种方式称呼它:

Kill("Zoey");
Kill("Francis", "Zoey");

string[] survivors = { "Zoey", "Francis", "Bill", "Louis" };

Kill(names);

(当然,假设你的幸存者都变成了僵尸!)

此外,风格上的C#代码通常使用pascal大小写来表示函数名称(KillAZombie而不是killAZombie)。

编辑附录

是的,参数排序 - 虽然它没有技术相关性 - 是API设计中的一个重要考虑因素,所以如果您要采用“不太重要”的参数,那么您可能不得不这样做{ {1}}。

话虽如此,我会坚持我的原始建议:由于该功能已命名(paramsKillZombie),我会坚持使用两个版本,只是为了让您的名字保持一致带参数。我还建议允许用户指定Kill而不是数组。这将允许开发人员使用实现IEnumerable<string>的任何内容传递名称,包括字符串数组。

答案 2 :(得分:3)

在这种情况下,我可能会考虑你的第二个建议。 KillZombie杀死一个僵尸; KillZombies杀死了多个僵尸。

另一种选择是使用带有params参数的单个方法:

KillZombies("foo");           // kill a single zombie
KillZombies("foo", "bar");    // kill multiple zombies

// ...

public void KillZombies(params string[] zombieLocations)
{
    foreach (string zombieLocation in zombieLocations)
    {
        // kills a zombie at specified location
    }
}

(另请注意,标准C#命名约定是使用大写“K”的KillZombie / KillZombies。)

答案 3 :(得分:2)

首先,不仅仅是这两种选择。

特别是,您可以使用第一种方法而无需额外的方法。

public void KillZombie(string zombieLocation){
    // Implement zombie killing logic here.
}

public void KillZombie(string[] zombieLocations){
    foreach(string zombieLocation in zombieLocations)
        KillZombie(zombieLocation);
}

但在这种情况下,我建议使用两种不同的方法。当然,他们做类似的事情,但一个拿僵尸,一个拿一个僵尸。方法名称应反映这一点。

类似地,.NET List类具有类似的方法AddAddRange

答案 4 :(得分:0)

你的例子遗憾地错了 - 你也可以使用params数组来允许这样的调用 KillZombies(location1,location2,location3)。 Params数组允许不确定参数数量。

也就是说,它通常是为了更容易使用而完成的。如果你有3个ovterloads因为它们全部被使用,那么拥有它们没有错,或者?

查看differentString.Format方法。

答案 5 :(得分:0)

如何使用它:

public void killZombies(string zombieLocation, params string[] zombieLocations){
    killZombie(zombieLocation);
    if(zombieLocations != null) {
        foreach(string zombieLocation in zombieLocations){
            killZombie(zombieLocation);
        }
    }
}

你可以传递一个或几个僵尸。

[编辑]注释,此更新禁止杀死没有僵尸