适用C#版本:4.0以后
首先给某些语言狂热分子泼点冷水,可选参数的概念来自Visul Basic而不是Ruby。在C# 2.0年代,并没有可选参数这个概念。 这个限制是因为在 C# 中,任何地方都引入面向对象思想,所以尽量使用重载而不是可选参数。
class MsgEcho
{
public MsgEcho():this("hi,world")
{
}
public MsgEcho(String name)
{
Console.WriteLine(name);
}
}
可选参数(Optional parameters)是C# 4.0的一个新特性,可以为一个方法的参数设置一个默认值。为一个参数设置一个默认值,这个参数就是可选参数,一旦被调用的方法忽略可选参数,就会用默认值代替。
为什么需要开放命名参数和可选参数呢?这是出于动态语言运行时兼容性的要求。动态语言中存在动态绑定的参数列表,有时候并不是所有的参数值都需要指定(有些语言可能没有重载决策);另外,在一些 COM 互操作时,往往 COM Invoke 的方法参数列表非常的长(例如 ExcelApplication.Save,可能需要 12 个参数),但 COM 暴露的参数的实际值往往为 null,只有很少一部分参数需要指定植,如 ExcelApplication.Save(),可能不需要指定任何参数值,或者仅仅一个值,例如 fileType
合 Visual Basic、Visual C++ 或者 Delphi 一样,C# 声明可选参数的方法就是在方法参数声明后面加上参数的默认值:
class MsgEcho
{
public MsgEcho(String name="hi,world")
{
Console.WriteLine(name);
}
}
代码中的name = ”hi,world“是可选参数。作用是传递一个“hi,world”字符串作为选用参数。使用可选参数有一些限制:
1. 可选参数必须从右往左出现在参数列表中(必须后出现),可选参数右边的参数(如果有的话)必须是可选参数。这些声明是非法的:
void Foo1(int a = 0, int b);
2.可选参数的初始值必须是一个在编译期可确定的常量,如果是除String之外的引用类型(包括那个特殊的dynamic类型),默认值只能是null。这些声明是非法的:
void Foo1(string name=String.Empty);
void Foo2(DateTime time=DateTime.Now);
3. 可选参数不可用ref,out等修饰符。
4. 调用带有多个可选参数的方法时,不可以置空以省略中间的某些参数,这样的调用时非法的:
Add(1,,3);//错误语法
而应该使用命名参数来调用该方法
Add(Param1:1,Param3:3);
面向对象的一个主要特征是:当调用对象上的某个方法的时候,由对象自己在运行时通过查找与对象关联的一张表来决定执行哪些代码,这被称为"dynamic dispatch",因此在对象中,可以有同名不同参数表的函数,即我们说的重载。
毫无疑问,命名参数和可选参数让CLR在方法的重载决策(overload resolution)变得稍微复杂了一些,因此在某些情况下,调用哪些代码是由重载决策来决定的:
1. 在带可选参数的方法签名中,重载决策不会认可被可选参数代替的重载版本:
public void Foo(int a, String s = "i'm a string", dynamic b = null, MyClass c = null);
public void Foo(int a, String s = "i'm a string");
如果按照以下方式调用,编译器会提示你它已经被上面两个方法confused了:
Foo(2);
Foo(a:2);
2. 在调用方式同样合法的情况下,重载决策会优先选择不带可选参数的重载版本。比如下面两个方法:
public void Foo(int a, String s = "i'm a string", dynamic b = null, MyClass c = null);
public void Foo(int a);
如果使用Foo(2)调用方法:被调用的会是void Foo(int a)这个版本:
3.同型的可选参数,如果不用命名参数赋值,则参数按从左到右的顺序被赋值
public void Foo(int a=0,int b=0);
如果使用Foo(2)调用方法,则a=2,b=0,可能与调用者的预期是不同的。
4.在调用方式同样合法的情况下,重载决策会优先选择类型最为匹配(最易转化)的重载,例如下面两个方法:
public void Foo(byte a, String s = "i'm a string", dynamic b = null, MyClass c = null);
public void Foo(object a);
Foo(2)和Foo(a:2)都将调用前一个方法,因为int到byte是值类型之间的转化,其代价要比从int转到object的代价低。
策略
在下面情况下,你应该考虑使用使用重载:
The logic in the procedure code is significantly different depending on whether the calling code supplies an optional argument or not.
The procedure code cannot reliably test whether the calling code has supplied an optional argument. This is the case, for example, if there is no possible candidate for a default value that the calling code could not be expected to supply.
在下面情况,你可以考虑使用一个或多个可选参数:
The only required action when the calling code does not supply an optional argument is to set the parameter to a default value. In such a case, the procedure code can be less complicated if you define a single version with one or more Optional parameters.
分享到:
相关推荐
第五章“方法”阐述了方法的定义、方法的格式化输出、参数的传递(值形参、引用形参、输出形参、形参数组)、参数默认值(可选参数)、命名参数以及方法重载的概念。方法是实现特定功能的代码块,是程序逻辑的重要...
在C# 4.0中,微软引入了多个关键改进和新特性,如动态类型、多语言互操作性(特别是与VB.NET和Python的互操作)、可选参数和命名参数、协程(通过Task Parallel Library实现)以及改进的异步编程模型等。这些变化...
C# 6.0引入了扩展方法、using静态导入、async Main等新特性,C# 7.0引入了模式匹配、out变量、本地函数等,C# 8.0及以后版本进一步增强了异步编程、引入了非空类型、可选参数等新特性。 "Csharp LanguageReference....
3. **可选参数和命名参数(Optional Parameters and Named Arguments)**:这些特性提高了方法调用的灵活性,使得接口更易于使用。 4. **协变和逆变(Covariance and Contravariance)**:C#4.0支持泛型接口的协变...
2. **可选参数(Optional Parameters)**:C# 4.0允许函数参数设置默认值,这意味着调用函数时可以省略这些参数,而不会导致编译错误。这对于提供更灵活的API接口和减少代码重复非常有用。 3. **命名和可空类型参数...
首先,C# 4.0作为.NET Framework的重要组成部分,引入了许多新的特性和改进,比如动态类型(dynamic)、命名参数(named arguments)和可选参数(optional parameters)。动态类型允许在运行时确定变量的类型,极大...
10. **命名参数和可选参数**:这两项特性提高了API的可用性,使得调用方法时可以更灵活地指定参数。 《Professional C# 2008》这本书会详细讲解这些特性,并通过实例和最佳实践来帮助读者理解和掌握。书中不仅涵盖...
2.6.3 命名参数和可选参数 2.7 本章小结 2.8 上机练习 2.9 习题 第3章 程序流程控制 3.1 选择结构程序设计 3.1.1 if语句 3.1.2 switch语句 3.2 循环结构程序设计 3.2.1 for语句 3.2.2 for each语句 3.2.3 while语句...
9.1 可选参数和命名参数 9.1.1 规则和原则 9.1.2 DefaultParameterValueAttribute和OptionalAttribute 9.2 隐式类型的局部变量 9.3 以传引用的方式向方法传递参数 9.4 向方法传递可变数量的参数 9.5 参数和...
9. **命名参数与可选参数(Named and Optional Parameters)**: 方法参数可以有默认值,也可以按照名称传递,提高代码可读性和灵活性。 10. **改进的异常处理(Exception Handling Improvements)**: 引入了`...
命名参数允许你在调用函数时按照参数名而非位置传递参数,而可选参数则允许函数接收默认值的参数,使得函数接口更加友好。 此外,C# 4.0对多目标框架的支持使得开发者可以编写兼容多个.NET Framework版本的代码,这...
可选参数则允许默认值的设定,使得函数签名更加简洁。 - **隐式实例化数组**:通过允许直接初始化数组而无需显式指定类型,C# 4.0简化了数组的使用。例如,可以使用`var numbers = new[] {1, 2, 3};`来声明和初始化...
此外,本章还介绍了main()方法的返回值和参数、参数的分类(值参数、引用参数、输出参数、参数数组)、递归、方法重载、可选参数以及如何使用异常处理基本错误。 第5章深入讲解了类的概念,包括类的定义和实例化、...
2. **命名参数和可选参数**:在方法调用时,可以指定参数名,使得代码更易读,同时,可选参数允许为方法提供默认值,减少不必要的重载。 3. **多态委托和Lambda表达式**:C# 4.0增强了委托的多态性,允许不同签名的...