方法重载与可选参数

3

我记得曾经读到过C# 4.0中方法重载(和构造函数链)与可选参数之间存在重要区别,但是我并没有找到任何承认差异的内容。

以下两种实现方式有哪些重要的区别?

第一种:

public void Foo()
{
   Foo(String.Empty);
}

public void Foo(string message)
{
   Console.WriteLine(message);
}

第二

public void Foo(string message = "")
{
   Console.WriteLine(message);
}

1
我对C#不是非常熟悉,但通常情况下方法重载是用于当你想要有不同类型的参数时。而使用可选参数时,它们只能是特定的类型。 - Sam Dufel
4个回答

9
我更喜欢方法重载。使用可选参数存在已知的版本问题,这里有相关文章。Jon Skeet写了一篇非常好的文章,在这里可以找到。增加此功能的动机是为了更容易地与COM交互,因为方法可能有很多参数,并且不适合用于C#类的新设计实践。请保留HTML标记。

“已知版本问题”实际上并不是一个问题,也不是反对使用可选参数的论据。它们只在下一个版本中修改方法时才会成为问题。但这可以通过添加重载而不是可选参数轻松解决。问题解决了(是的,Phil说了其他的话,但他犯了一个错误,因为他使新的参数可选)。 - Konrad Rudolph
目前,Jon Skeet文章的链接已经失效。现在无法编辑此答案,所以这是一个存档链接 - Loz

3

可选参数就像常量一样,在编译时被替换。

public void Foo(string s = "default")
Foo();

将为调用者生成代码:

public void Foo(string s)
Foo("default");

这意味着如果您选择在新版本中更改默认设置,引用您的所有程序集都将具有旧的默认设置!

重载不像常量一样,并且隐藏了您程序集中的默认设置。这为清洁的升级路径提供了可能。


1
我会选择第二个选项。您可以将默认字符串更改为某个常量,然后在以后的日期更改常量的值,例如:
constant String defaultString = String.Empty; //change this later if the default value needs to be something else, can't remember if the syntax is valid C# ;)
//...
public void Foo(string message = defaultString)
{
   Console.WriteLine(message);
}

此外,您需要维护的函数少了一个(虽然很简单)。


我不记得有任何关于方法重载和可选参数之间功能上的主要差异的讨论,因此为了代码维护的缘故,我会默认使用可选参数,并且只有在某些情况下需要时才使用重载。 - AllenG
k_dflt_str” - 什么?不行,不不不不。 - Konrad Rudolph
@Konrad Rudolph:嘿,我们的大脑目前处于PL/SQL标准模式。 ;) - FrustratedWithFormsDesigner

0

可选参数是语法糖。

除了与之前版本的.NET向后兼容外,它们是相同的。


他们的IL不同,让我认为它们在JIT之后仍然不同。向后兼容性也值得商榷,因为可选参数在IL中比.NET 4早就得到支持。 - Yuriy Faktorovich

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接