C#4.0中的更改——命名参数和可选参数
Posted DinAction
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#4.0中的更改——命名参数和可选参数相关的知识,希望对你有一定的参考价值。
一、概念
C#中的命名参数和可选参数是两种函数参数的特殊形式,它们可以提高代码的可读性和灵活性。
命名参数
命名参数允许我们在调用函数时指定参数名称,从而不必按照函数定义时的参数顺序进行传参。这样做可以使代码更加易读易懂,同时也可以提高代码的灵活性,因为我们可以只传递某些参数来设置默认值。
以下是一个使用命名参数的示例:
void PrintPerson(string firstName, string lastName, int age)
Console.WriteLine($"Name: firstName lastName, Age: age");
// 使用命名参数调用PrintPerson函数
PrintPerson(lastName: "Smith", firstName: "John", age: 30);
在上面的示例中,我们使用了命名参数来调用PrintPerson函数,并且没有按照函数定义时的参数顺序进行传参。由于我们指定了每个参数的名称,因此代码更加易读易懂。
注意,当我们使用命名参数时,可以省略一些参数并采用默认值,但不能跳过非可选参数。例如,下面的代码是无法编译通过的:
PrintPerson(lastName: "Smith"); // 编译错误:缺少必需的参数 \'firstName\' 和 \'age\'
可选参数
可选参数允许我们在函数定义时为某些参数指定默认值,从而在调用函数时可以不传递这些参数。这样做可以提高代码的灵活性,因为我们可以只传递需要的参数,而不必传递所有参数。
以下是一个使用可选参数的示例:
void PrintPerson(string firstName, string lastName, int age = 18)
Console.WriteLine($"Name: firstName lastName, Age: age");
// 调用PrintPerson函数
PrintPerson("John", "Smith"); // 输出结果:Name: John Smith, Age: 18
PrintPerson("Mary", "Johnson", 25); // 输出结果:Name: Mary Johnson, Age: 25
在上面的示例中,我们定义了一个可选参数age,并将其默认值设置为18。当我们调用PrintPerson函数时,如果没有传递age参数,则会使用默认值。
注意,当我们使用可选参数时,必须将它们放在函数签名的末尾,并且不能使用ref或out关键字。例如,下面的代码是无法编译通过的:
void PrintPerson(string firstName, string lastName, ref int age = 18) // 编译错误:可选参数不能使用ref或out关键字
Console.WriteLine($"Name: firstName lastName, Age: age");
总之,命名参数和可选参数都是C#中非常有用的语言特性,它们能够提高代码的可读性和灵活性,使程序变得更加易于维护和扩展。
二、实例
命名参数和可选参数的应用场景非常广泛,以下是一些经典的应用场景,并附有相应的代码示例:
命名参数
- 函数具有多个参数,但我们只关心其中的某几个参数。
void PrintPerson(string firstName, string lastName, int age)
Console.WriteLine($"Name: firstName lastName, Age: age");
// 使用命名参数调用PrintPerson函数,只传递了需要的参数
PrintPerson(lastName: "Smith", firstName: "John");
- 函数中具有相同类型的多个参数,使用命名参数可以提高代码的可读性。
void Search(int id, string name, string address)
// ...
// 使用命名参数调用函数Search,可以清楚地表明每个参数的含义
Search(id: 1, name: "John", address: "123 Main St.");
可选参数
- 函数中某些参数的默认值可能经常被使用。例如,在创建一个窗口时,我们可以将宽度和高度设置为可选参数,并将其默认值设置为800和600,因为这是大多数用户所期望的窗口大小。
void CreateWindow(int width = 800, int height = 600)
// ...
// 调用CreateWindow函数,不传递可选参数
CreateWindow(); // 窗口大小为800x600
// 调用CreateWindow函数,只传递一个可选参数
CreateWindow(width: 1024); // 窗口大小为1024x600
// 调用CreateWindow函数,传递两个可选参数
CreateWindow(width: 1024, height: 768); // 窗口大小为1024x768
- 函数中的某些参数是可选的,但如果提供了,则必须按照特定的格式进行传递。例如,在打印日志时,我们可以将时间戳设置为一个可选参数,并将其默认值设置为当前时间。
void Log(string message, DateTime timestamp = default(DateTime))
if (timestamp == default(DateTime))
timestamp = DateTime.Now;
Console.WriteLine($"[timestamp] message");
// 调用Log函数,不传递可选参数
Log("Hello World!"); // 输出结果:[2021/10/01 12:00:00] Hello World!
// 调用Log函数,传递时间戳作为可选参数
Log("Hello World!", new DateTime(2021, 9, 30, 23, 59, 59)); // 输出结果:[2021/09/30 23:59:59] Hello World!
总之,命名参数和可选参数是一种非常有用的C#语言特性,它们能够提高代码的可读性和灵活性。在实际开发中,我们应该根据具体场景选择合适的参数传递方式,以使代码更加清晰易懂。
通用方法和可选参数
【中文标题】通用方法和可选参数【英文标题】:Generic methods and optional arguments 【发布时间】:2012-04-11 00:51:54 【问题描述】:可以写出类似的结构吗? 我想以某种方式为 T 类型的参数设置默认值。
private T GetNumericVal<T>(string sColName, T defVal = 0)
string sVal = GetStrVal(sColName);
T nRes;
if (!T.TryParse(sVal, out nRes))
return defVal;
return nRes;
另外,我发现了以下链接: Generic type conversion FROM string 我认为,这段代码必须有效
private T GetNumericVal<T>(string sColName, T defVal = default(T)) where T : IConvertible
string sVal = GetStrVal(sColName);
try
return (T)Convert.ChangeType(sVal, typeof(T));
catch (FormatException)
return defVal;
【问题讨论】:
【参考方案1】:我没有尝试过,但将T defVal = 0
更改为T defVal = default(T)
【讨论】:
【参考方案2】:如果你知道 T 会有一个无参数的构造函数,你可以这样使用 new T():
private T GetNumericVal<T>(string sColName, T defVal = new T()) where T : new()
否则你可以使用默认(T)
private T GetNumericVal<T>(string sColName, T defVal = default(T))
【讨论】:
【参考方案3】:回答设置默认值的问题
private T GetNumericVal<T>(string sColName, T defVal = default(T))
string sVal = GetStrVal(sColName);
T nRes;
if (!T.TryParse(sVal, out nRes))
return defVal;
return nRes;
但是你不能调用静态 TryParse 方法,因为编译器无法知道类型 T 声明了这个静态方法。
【讨论】:
是的,我不能调用 TryParse。但也许类似的东西?也许为类型参数添加一些约束(我的意思是'where:...')?如果数字类型实现了一些转换接口。 CLR 没有“虚拟静态方法”的概念,编译器无法从类型推断静态方法。据我所知,没有干净的解决方案。 ***.com/questions/196661/… 了解更多详情以上是关于C#4.0中的更改——命名参数和可选参数的主要内容,如果未能解决你的问题,请参考以下文章