在C#中使用解构语法将元组和对象解构到变量

解构元组

元组用于将不同类型的对象合并在一起,通常用于在方法中返回多个值。

 public (string Name, int Age, int Score) GetStudent()
 {
     var name = "小红";
     var age = 13;
     var score = 90;
     return (name, age, score);
 }

在引入元组之前,要返回这样三个值,要么定义一个类包装,要么使用 out 参数,有了元组之后,out 参数的使用需求极大降低了。

 public void GetStudent(out string Name, out int Age, out int Score)
 {
     Name = "小红";
     Age = 13;
     Score = 90;
 }

可以直接使用元组对象来获取值。

 var student = GetStudent();
 Console.WriteLine(#34;{student.Name},年龄 {student.Age},得分 {student.Score}");

但有时可能需要解构到本地变量,可以用以下方法。

 (string name, int age, int score) = GetStudent();
 
 // 或者更简洁的写法
 var (name,age,core) = GetStudent();

个人感觉,作用不是特别大,最常用的场景还是用于解构对象。

解构对象

构造函数我们已经很熟悉了,通常是接受若干个参数,运行初始化代码,生成并返回新创建的对象。解构函数正好相反,是根据对象的状态计算出若干个值返回外部调用者。

在 C# 中,解构函数的名称必须是 Deconstruct,返回值 void ,要解构到的变量用 out 参数实现。

 public class Student
 {
     public string Name { get; set; } = default!;
     public int Age { get; set; }
     public int Score { get; set; }
     public void Deconstruct(out string name, out int age, out int score)
     {
         name = Name;
         age = Age;
         score = Score;
     }
 }

定义了解构函数后,就可以使用元组语法来将对象解构到变量了。

 var student = new Student() { Name = "小红", Age = 13, Score = 90 };
 
 (string name, int age, int score) = student;
 // 输出:小红,13岁,成绩90分
 Console.WriteLine(#34;{name},{age}岁,成绩0{score}分");

上述第二行代码是解构语法,是以下代码的语法糖。

 student.Deconstruct (out string name,out int age,out int score);

结构语法也支持隐式类型推定。

  (var name, var age, var score) = student;

或者,更简洁的:

 var (name, age, score) = student;

如果在解构时你只需要其中部分变量,那么不需要的可以使用弃元符号 _ ,这样就不用声明一个不需要的变量了。

 // 只对名称和年龄感兴趣
 var (name, age, _) = student;
 
 // 只对名称和分数感兴趣
 var (name, _, score) = student;
 
 // 只对名称感兴趣
 var (name, _, _) = student;

从 C# 10 开始,结构语法还支持已有变量和新建变量的混合使用。

 string name;
 (name, var age, var score) = student;

看到这儿,小伙伴们应该也明白了,其实解构元组和解构对象是一样的,解构对象只是在对象类里面定义了一个通过 out 返回值的固定名称的解构函数,其余没有任何区别。

同时,C# 9.0 引入了记录 Record 类型,本质上也是一个类,且自动实现了解构函数,使用更加简单。

 record Student(string Name, int Age, int Score);
 var student = new StudentRecord("小红", 13, 90);
 var (name, age, score) = student;



发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章