C# 8.0 新特性: 解构(这是 C#7 的新特性,之前忘了写了), ??=, 集合的倒序索引和范围索引, switch 表达式, 默认接口方法





介绍

C# 8.0 新特性


  • 解构(这是 C#7 的新特性,之前忘了写了)
  • ??=
  • 集合的倒序索引和范围索引
  • switch 表达式
  • 默认接口方法


示例

1、演示“解构”(这是 C#7 的新特性,之前忘了写了)

DeconstructDemo.cs


/*  * 本例用于演示“解构”(这是 C#7 的新特性,之前忘了写了)  */  using System;  namespace CSharp8 {     public class DeconstructDemo     {         class User         {             public string Name { get; set; }             public int Age { get; set; }             public string Email { get; set; }              // 构造函数(用于通过指定的参数构造出一个对象)             public User(string name, int age, string email)              {                 Name = name;                 Age = age;                 Email = email;             }              // 解构函数(用于解构出对象的参数)             public void Deconstruct(out string name, out string email)             {                 name = Name;                 email = Email;             }              // 解构函数(用于解构出对象的参数),解构函数支持重载             public void Deconstruct(out string name, out int age, out string email)             {                 name = Name;                 age = Age;                 email = Email;             }         }         public static void Demo()         {             // 调用构造函数实例化             var user = new User("webabcd", 40, "webabcd@gmail.com");              // 调用解构函数,用于解析出对象的参数             (var n1, var e1) = user;             Console.WriteLine($"name:{n1}, email:{e1}"); // name: webabcd, email: webabcd @gmail.com              // 调用解构函数,用于解析出对象的参数             (var n2, var a2, var e2) = user;             Console.WriteLine($"name:{n2}, age:{a2}, email:{e2}"); // name:webabcd, age: 40, email: webabcd @gmail.com         }     } }


2、演示 ??=, 集合的倒序索引和范围索引

New1.cs


/*  * C#8 新特性  * 1、??=  * 2、集合的倒序索引和范围索引  */  using System;  namespace CSharp8 {     public class New1     {         public static void Demo()         {             Sample1();             Sample2();         }          // 演示 ??=         public static void Sample1()         {             // 演示 ??             string a = null;             a = a ?? "a is null";             Console.WriteLine(a); // a is null              // 演示 ??=             string b = null;             b ??= "b is null";             Console.WriteLine(b); // b is null         }                   // 演示集合的范围索引(支持倒序索引和范围索引)         public static void Sample2()         {             var ary = new string[]             {                         // 正序索引     倒序所索引                 "m1",   // 0            ^5                 "m2",   // 1            ^4                 "m3",   // 2            ^3                 "m4",   // 3            ^2                 "m5",   // 4            ^1             };              // 正序索引             Console.WriteLine(ary[4]); // m5              // 倒序索引             Console.WriteLine(ary[^1]); // m5              // 范围索引             // 1、左侧不指定位置则为最开始             // 2、右侧不指定位置则为最末尾             // 3、右侧指定位置时,取值范围不包括其指定的位置             Console.WriteLine(string.Join(',', ary[0..5])); // m1,m2,m3,m4,m5             Console.WriteLine(string.Join(',', ary[0..^0])); // m1,m2,m3,m4,m5             Console.WriteLine(string.Join(',', ary[..])); // m1,m2,m3,m4,m5             Console.WriteLine(string.Join(',', ary[..3])); // m1,m2,m3             Console.WriteLine(string.Join(',', ary[3..])); // m4,m5              // Range 结构体             Range range = 0..2;             Console.WriteLine(string.Join(',', ary[range])); // m1,m2         }     } }


3、演示 switch 表达式

SwitchExpression.cs


/*  * C#8 新特性:switch 表达式  *   * 注意:这里说的 C#8 的新特性是 switch 表达式(switch expression),而不是 switch 语句(switch statement)  */  using System;  namespace CSharp8 {     public class SwitchExpression     {         public static void Demo()         {             Sample1();             Sample2();             Sample3();             Sample4();         }           // 简单演示一下 switch 表达式的使用         public static void Sample1()         {             string SwitchExpression(string input) =>                 input switch                 {                     "1" => "111111",                     "2" => "222222",                     _ => "000000" // 这里的“_”相当于 switch 语句中的 default                 };              Console.WriteLine(SwitchExpression("1")); // 111111             Console.WriteLine(SwitchExpression("2")); // 222222             Console.WriteLine(SwitchExpression("1234")); // 000000         }           class A         {             public string Name { get; set; }             public int Age { get; set; }         }         // switch 表达式中的属性匹配的示例         public static void Sample2()         {             string PropertyPattern(A a, int salary) =>                 a switch                 {                     { Name: "name1" } => $"name:{a.Name}, age:{a.Age}, salary:{salary}",                     _ => "000000"                 };              Console.WriteLine(PropertyPattern(new A { Name = "name1" }, 100)); // name:name1, age:0, salary:100             Console.WriteLine(PropertyPattern(new A { Name = "name2" }, 100)); // 000000         }           // switch 表达式中的元组(Tuple)匹配的示例         public static void Sample3()         {             string TuplePattern(string first, string second) =>                 (first, second) switch                 {                     ("a", "b") => $"first:{first}, second:{second}",                     _ => "000000"                 };              Console.WriteLine(TuplePattern("a", "b")); // first:a, second:b             Console.WriteLine(TuplePattern("c", "d")); // 000000         }           class B         {             public string Name { get; set; }             public int Age { get; set; }              public void Deconstruct(out string name, out int age)             {                 name = Name;                 age = Age;             }         }         // switch 表达式中的可结构对象匹配的示例         public static void Sample4()         {             string PositionalPattern(B b) =>                 b switch                 {                     ("webabcd1", 20) => "aaaaaa",                     var (x, y) when y > 30 => "bbbbbb", // 要支持这种写法,则对象必须要实现相应的解构函数                     _ => "000000"                 };              Console.WriteLine(PositionalPattern(new B { Name = "webabcd1", Age = 20 })); // aaaaaa             Console.WriteLine(PositionalPattern(new B { Name = "webabcd2", Age = 30 })); // 000000             Console.WriteLine(PositionalPattern(new B { Name = "webabcd3", Age = 40 })); // bbbbbb         }     } }


4、演示默认接口方法

DefaultInterfaceMethods.cs


/*  * C#8 新特性:默认接口方法  */  using System;  namespace CSharp8 {     // 接口可以有自己的默认方法了     interface IA     {         void M1();         void M2() { Console.WriteLine("IA.M2"); }         void M3() => Console.WriteLine("IA.M3");     }      // 类在继承接口时,如果接口的某个方法有自己的默认方法,则类可以不去实现此方法     class B : IA     {         public void M1() { Console.WriteLine("B.M1"); } // 必须实现此方法         public void M2() { Console.WriteLine("B.M2"); } // 可以不实现此方法,如果实现了则覆盖          // 可以不实现接口的 M3() 方法     }      public class DefaultInterfaceMethods     {         public static void Demo()         {             B b = new B();             b.M1(); // B.M1             b.M2(); // B.M2              // 注意:对象 b 是没有 M3() 方法的             // b1.M3();               // 如果要想调用对象 b 的 M3() 方法,则可以这么写             IA a = b;             a.M3(); // IA.M3         }     } }