在 C# 中实现默认参数的解决方法






2.17/5 (9投票s)
2006年10月11日
2分钟阅读

29754
本文介绍了一种使用参数数组功能在 C# 中实现默认参数的变通解决方案。
引言
在学习 Java 时,C++ 中我为数不多的怀念之一就是默认参数功能。我一直希望 C# 能够重新引入此功能。不幸的是,在我开始学习 C# 的那天,我被告知 C# 中没有默认参数功能。我当时想,好吧,没有默认参数我们也能活下去。然而,在过去编写 C# 程序的几年里,我就是无法将默认参数从我的脑海中抹去。我不时地遇到一些情况,如果使用默认参数,就可以节省时间,甚至可能提高性能。所以,现在我正在尝试一些巧妙/笨拙的解决方案。
背景
如果你听说过“参数数组”或“可变参数”或“params
”关键字,这个想法就很简单。C# 的“params
”关键字允许你为方法指定可变数量的参数。我猜 99% 的 C# 代码编写者都使用过参数数组,因为我们非常好的朋友 Console.WriteLine(...)
本身就可以接受可变数量的参数。如果你想编写自己的接受参数数组的方法,你需要使用“params
”关键字。 它的工作方式如下:
void PrintNumbers(params int[] numbers)
{
Console.WriteLine("Count: {0}", numbers.Length);
foreach (int n in numbers)
{
System.Console.WriteLine(numbers);
}
}
void Test()
{
PrintNumbers();
PrintNumbers(1);
PrintNumbers(2, 3);
PrintNumbers(4, 5, 6);
PrintNumbers(7, 8, 9, 10);
// Basically you can go on like this forever,
// and they all call exactly the same method above.
}
现在,参数数组意味着任意数量的参数(0 个或更多),而默认参数意味着 0 个或 1 个参数。 显然,默认参数只是参数数组的一种特殊情况。实现
现在,让我们使用“params
”关键字来获取默认参数。
class DefaultParameterTest
{
private const int DEFAULT_ARG = 0;
/// <summary>
/// Purpose of this method...
/// </summary>
/// <param name="fixedArg">meaning of this parameter...</param>
/// <param name="defaultArg">
/// meaning of this parameter...
/// Note that this parameter is optional, and its default value is 0.
/// </param>
void TakeDefaultArgument(int fixedArg, params int[] defaultArg)
{
if (defaultArg.Length > 1)
throw new ArgumentException("Too many arguments");
int defaultArgValue;
if (defaultArg.Length == 0)
defaultArgValue = DEFAULT_ARG;
else
defaultArgValue = defaultArg[0];
// use defaultArgValue for the following part of the method
// ...
}
void Test()
{
// The following 3 calls achieve exactly the same result.
// use default argument
TakeDefaultArgument(9);
// use user specified argument
TakeDefaultArgument(9, 0);
// a wired way to pass in user defined argument, but legal
TakeDefaultArgument(9, new int[] { 0 });
// The following calls are invalid
// compilation error
TakeDefaultArgument(9, "0");
// no compilation error or warning, but runtime exception
TakeDefaultArgument(9, 0, 1);
}
}
我使用 int
进行说明,但基本上默认参数可以是任何类型。
关注点
这种变通方法有很多局限性和缺点。(否则它就不会被称为“变通方法”了)。以下是其中的一些:
“可默认”参数的数量仅限于一个,并且必须位于参数列表的末尾。
默认参数是类型安全的。但是,当你的默认参数本身的类型是数组时,它会变得非常棘手。(稍后可能会对此进行更多讨论。)
如果传入的参数过多,则不会出现编译错误,甚至不会出现警告。异常将在运行时抛出。这很痛苦,因为错误检查从编译时转移到运行时,效率更低且更危险。
你可以传入一个只有一个元素的数组,它仍然有效,尽管该方法期望 0 个或 1 个元素作为参数。 这是因为 C# 参数数组不仅可以接受单个或多个参数,还可以接受单个参数数组。
你无法在方法的签名中看到默认值。 我能想到的最好的解决方案是以明显的方式将默认值放在 XML 样式注释中。
因此,请注意:如果你想这样使用默认参数,请非常仔细地记录你的方法,以确保其他使用此方法的人都清楚地知道发生了什么。
历史
- 2006 年 10 月 11 日 - 初稿。