博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

C# 8.0 新特性

Posted on 2020-11-03 13:32  webabcd  阅读(175)  评论(1编辑  收藏

[源码下载]


C# 8.0 新特性



作者:webabcd


介绍
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
        }
    }
}



OK
[源码下载]