总目录
前言
在C# 7.0及更高版本中,弃元(Discard)是一个新的语言特性,允许开发者在特定情况下忽略某些值。弃元用下划线 _
作为占位符,明确表示忽略某个值,提升代码可读性
一、弃元是什么?
1. 基本概念
弃元(Discard)是 C# 7.0 引入的占位符变量,用下划线 _
表示,用于显式声明某个值无需使用。它不会分配内存空间,甚至能减少编译器警告,让代码意图更明确。
- 弃元是 C# 中的一个语言特性,用于在声明变量或表达式时显式地指定一个“不关心”的占位符。
- 它使用下划线 _ 作为标识符,告诉编译器在这里不需要分配内存或存储数据,仅仅是为了语法的完整性而存在。
- 从 C# 7.0 开始,C# 支持弃元,这是一种在应用程序代码中人为取消使用的占位符变量。 弃元相当于未赋值的变量;它们没有值。 因为只有一个弃元变量,甚至不为该变量分配存储空间,所以弃元可减少内存分配。 因为它们使代码的意图清楚,增强了其可读性和可维护性。
2. 核心特性
- 内存零分配:编译器不为弃元变量分配存储空间(弃元不存储值)
- 意图明确化:明确告知开发者和编译器“此值无需使用”,编译器可能优化相关代码
- 跨场景适配:适用于元组、模式匹配、异步编程等20+种场景
3. 注意事项
-
不可读取值:弃元
_
一旦声明,后续代码中不能访问其值。var _ = 10; Console.WriteLine(_); // 编译错误:弃元不可读取
-
作用域限制:同一作用域内
_
只能作为弃元,不能重新定义为普通变量。 -
与
var
的区别:var
是类型推断,_
是显式弃元。
二、弃元的使用
1. 元组和对象的析构
对于Deconstruct 不了解的,可以查看C# Deconstruct详解。
1)元组的析构
如果应用程序代码使用某些元组元素,但忽略其他元素,这时使用弃元来处理元组就会很有用
// 使用弃元忽略元组中的第一个和第二个元素var(_,_,id) = ("jack","123",3);
static void Main(string[] args){//通过使用 弃元,忽略age的值,只取name的值(var name, _) = GetUser();Console.WriteLine($"name:{name}");Console.ReadKey();}//该方法 返回类型为 元组 public static (string name, int age) GetUser(){return ("张三", 33);}
2)对象的析构
类、结构或接口的 Deconstruct 方法还允许从对象中检索和析构一组特定的数据。 如果想只使用析构值的一个子集,可使用弃元。
定义一个Person类,并在该类中定义了多个析构函数
public class Person{public string FirstName { get; set; }public string MiddleName { get; set; }public string LastName { get; set; }public string City { get; set; }public string State { get; set; }//定义构造函数public Person(string fname, string mname, string lname,string cityName, string stateName){FirstName = fname;MiddleName = mname;LastName = lname;City = cityName;State = stateName;}// 定义析构函数public void Deconstruct(out string fname, out string lname){fname = FirstName;lname = LastName;}// 定义析构函数的重载public void Deconstruct(out string fname, out string mname, out string lname){fname = FirstName;mname = MiddleName;lname = LastName;}// 定义析构函数的重载public void Deconstruct(out string fname, out string lname,out string city, out string state){fname = FirstName;lname = LastName;city = City;state = State;}}
析构函数的运用,Person中有很多的属性,但是我只想取得其中部分属性的值:
class Example{public static void Main(){var p = new Person("John", "Quincy", "Adams", "Boston", "MA");// 析构Person这个对象,并且只获取fName 和 city两个参数,其余的忽略var (fName, _, city, _) = p;Console.WriteLine($"Hello {fName} of {city}!");// Hello John of Boston!}}
2. 匹配模式中的弃元
static void Main(){object obj = new int[] { 1, 2, 3 };switch (obj){case int[] _ when ((int[])obj).Length > 2:Console.WriteLine("数组长度大于2");break;case null:Console.WriteLine("空值");break;default:Console.WriteLine("其他类型");break;}}
internal class MyClass{private int v1;private string v2;public MyClass(int v1, string v2){this.v1 = v1;this.v2 = v2;}}static void Main(string arg){object obj = new MyClass(10, "test");// 使用弃元忽略 MyClass 对象if (obj is MyClass _){Console.WriteLine("Matched MyClass type");}}
3. 异步方法中的弃元
明确表达“关注执行而非结果”
// 异步执行且忽略返回值static void Main(){_ = Task.Run(() => Log("异步任务执行"));}public static void Log(string data){Console.WriteLine(data);}
static void Main(string arg){_= GetResultAsync(); // 使用弃元忽略异步方法的结果}async static Task<int> GetResultAsync(){await Task.Delay(1000);return 10;}
4. out
参数与方法返回值
// 忽略 TryParse 的布尔返回值
int.TryParse("123", out _); // 忽略方法返回值
_ = GetConfig(); // 假设 GetConfig() 返回重要配置
注意:弃元不能读取值,否则会报错 CS0103
5. 迭代元素时的弃元
迭代元素时的弃元: 用于忽略迭代过程中的某些值。
var dictionary = new Dictionary<string, int>
{["apple"] = 1,["banana"] = 2,["cherry"] = 3
};// 使用弃元忽略键,只处理值
foreach (var (_, value) in dictionary)
{Console.WriteLine(value); // 输出:1 2 3
}
6. 独立弃元与空合并运算符
// 独立弃元:强制空值检查
_ = arg ?? throw new ArgumentNullException(); // 结合 null 合并运算符
var result = data ?? _ = LoadData();
场景:
- 防止空引用异常
- 确保副作用(如
LoadData()
)被执行
弃元是 C# 提升代码简洁性的“语法糖”,通过合理使用下划线 _
,能够帮助开发人员编写更为简洁和清晰的代码。通过使用弃元,可以有效地忽略不需要的变量或返回值,提高代码的可读性和维护性。在实际开发中,根据需要合理地运用弃元,可以使代码更加精简和易于理解。
结语
回到目录页:C# 知识汇总
以上就是本文的内容,希望以上内容可以帮助到您,如文中有不对之处,还请批评指正。
参考资料:
弃元 - C#指南
C# 弃元的详解与示例
MSDN弃元
MSDN析构元组