C# 10个常用特性汇总
在本文中,我们将介绍 C# 中的10个常用特性及其用例,包括:
- 可空引用类型(Nullable reference types)
- 模式匹配(Pattern matching)
- 捕获块(Catch block)
- 局部函数(Local functions)
- 海象运算符(Null coalescing assignment operator)
- 设计时验证(Design-time validation)
- 命名参数(Named arguments)
- 函数式编程模式(Functional programming pattern)
- 数字分隔符(Digit separators)
- Lambda 表达式多行(Multi-line lambda expressions)
1. 可空引用类型
在 C# 8.0 中,引入了可空引用类型特性,它可以防止出现空引用异常。这样一来,我们就可以通过编译器检测空引用,从而避免空引用异常的发生。
示例代码如下:
// 当没有开启可空引用类型特性时
string name = null;
Console.WriteLine(name.Length); // 会抛出 NullReferenceException 异常
// 当开启了可空引用类型特性时
string? nullableName = null;
Console.WriteLine(nullableName.Length); // 会编译报错,提示 nullableName 可能为 null
2. 模式匹配
模式匹配可以根据类型、结构、枚举等进行筛选,可以让代码更加简洁清晰。在 C# 9.0 中,引入了新的语法,可以使用关键字 and
和 or
来进行多个条件的匹配。
示例代码如下:
object obj = "Hello, World!";
if (obj is string s && s.StartsWith("Hello"))
{
Console.WriteLine("Hello, World!");
}
else if (obj is string t or int i)
{
Console.WriteLine(t ?? i);
}
如果 obj 是字符串并且以 “Hello” 开头,那么会输出 “Hello, World!”;如果 obj 是字符串或者整数,则会输出 obj 的值。
3. 捕获块
在 C# 6.0 中引入了捕获块特性,它可以让我们在 try-catch 中捕获到特定的异常类型,并赋值给一个变量,从而可以方便的使用该变量。
示例代码如下:
try
{
// some error
}
catch (Exception ex) when (ex is ArgumentException || ex is NullReferenceException)
{
Console.WriteLine($"Caught exception: {ex.GetType().Name}");
}
这样,我们就可以捕获 ArgumentException 和 NullReferenceException 两种异常类型,并将异常赋值给 ex 变量。
4. 局部函数
局部函数是在一个函数内部定义的函数,可以方便地在该函数内部使用。局部函数可以访问其所在函数的变量和参数,但是不能被外部调用。
示例代码如下:
static int Add(int a, int b)
{
return AddInner();
int AddInner()
{
return a + b;
}
}
在这个例子中,AddInner 是 Add 函数的一个局部函数,它可以访问 a 和 b 变量。
5. 海象运算符
在 C# 9.0 中,引入了一个新的运算符,又称为空合并赋值运算符 ??=
。它可以用于检查变量是否为 null,如果为 null,则赋予一个默认值。
示例代码如下:
string name = null;
name ??= "David";
Console.WriteLine(name); // 输出 David
在这个例子中,当 name 为 null 时,默认值 “David” 被赋予给 name。
6. 设计时验证
在开发过程中,有时会出现一些代码写错,但是编译器不会检测到的问题。在 C# 9.0 中,引入了设计时验证特性,可以在开发环境中对代码进行自动检查。
示例代码如下:
[NotNull]
void Buy([NotNull] string itemName, int quantity)
{
// ...
}
在这个例子中,使用 NotNull 属性进行设计时验证,可以检查 itemName 和 quantity 变量是否为 null,如果是,编译器就会提示错误。
7. 命名参数
在 C# 中,可以使用命名参数对函数的参数进行命名标识,这样可以方便地传递参数,并且代码更加易读。
示例代码如下:
void SendMessage(string text, string from = "Admin", string to = "User")
{
Console.WriteLine($"[{from}] -> [{to}]: {text}");
}
SendMessage("Hello"); // 输出 [Admin] -> [User]: Hello
SendMessage("Hi", to: "Someone"); // 输出 [Admin] -> [Someone]: Hi
在这个例子中,强制要求传入 text 参数,但是 from 和 to 参数使用了默认值,当不传入参数时,会自动使用默认值。
8. 函数式编程模式
在 C# 8.0 中,引入了一些函数式编程模式,包括:switch 表达式,范型协变和逆变等。这些特性可以让代码更加简洁易读,并且可以支持更加复杂的逻辑。
示例代码如下:
var result = id switch
{
int i when i < 0 => "negative",
int i when i >= 0 => "positive",
_ => "unknown"
};
在这个例子中,使用 switch 表达式将变量 id 进行分支,根据不同的分支条件返回不同的值。使用 switch 表达式可以避免 switch 语句中的冗长重复。
9. 数字分隔符
数字分隔符是一个辅助数值的分组符号,可以提高代码可读性。在 C# 7.0 中,引入了数字分隔符特性,可以使用下划线来分隔大整数的位数。
示例代码如下:
int amount = 1_000_000;
在这个例子中,使用下划线来分隔千位数,可以让代码更加清晰易读。
10. Lambda 表达式多行
在 C# 7.0 中,Lambda 表达式支持多行定义,可以使代码更加直观。
示例代码如下:
Func<int, int> factorial = x =>
{
int result = 1;
for (int i = 1; i <= x; i++)
{
result *= i;
}
return result;
};
在这个例子中,使用 Lambda 表达式定义了一个阶乘函数,使用多行定义可以方便地写出更加复杂的函数。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C# 10个常用特性汇总 - Python技术站