15.模式匹配增强

  1. 15.CSharp各版本新功能和语法-CSharp8功能和语法-模式匹配增强
    1. 15.1 知识点
      1. 模式匹配回顾
      2. switch表达式
      3. 属性模式
      4. 元组模式
      5. 位置模式
    2. 15.2 知识点代码

15.CSharp各版本新功能和语法-CSharp8功能和语法-模式匹配增强


15.1 知识点

模式匹配回顾

模式匹配(Pattern Matching)是一种测试表达式是否具有特定特征的方法,在编程中指的是通过一些固定的语法格式来确定模式数据的具体内容的过程。

我们目前学习过的模式匹配包括:

  1. 常量模式(is 常量):用于判断输入值是否等于某个值。
object o = 1.5f;
if (o is 1)
{
    print("o是1");
}
if (o is null)
{
    print("o是null");
}
  1. 类型模式(is 类型 变量名、case 类型 变量名):用于判断输入值类型,如果类型相同,将输入值提取出来。
if (o is int i)
{
    print(i);
}
switch (o)
{
    case int value:
        print("int:" + value);
        break;
    case float value:
        print("float:" + value);
        break;
    case null:
        print("null");
        break;
    default:
        break;
}
  1. var模式:用于将输入值放入与输入值相同类型的新变量中。
if (o is var v)
{
    print(v);
}

switch表达式

switch表达式是对有返回值的switch语句的缩写,用=>表达式符号代替case:组合,用_弃元符号代替default。它的使用限制,主要是用于switch语句当中只有一句代码用于返回值时使用。

语法:

函数声明 => 变量 switch
{
    常量=>返回值表达式,
    常量=>返回值表达式,
    常量=>返回值表达式,
    ....
    _ => 返回值表达式,
}

举例:

public Vector2 GetPos(PosType type) => type switch
{
    PosType.Top_Left => new Vector2(0, 0),
    PosType.Top_Right => new Vector2(1, 0),
    PosType.Bottom_Left => new Vector2(0, 1),
    PosType.Bottom_Right => new Vector2(1, 1),
    _ => new Vector2(0, 0)
};

print(GetPos(PosType.Bottom_Right));

属性模式

属性模式在常量模式的基础上判断对象上各属性,使用方法为变量 is {属性:值, 属性:值}。

举例:

public class DiscountInfo
{
    public string discount; // 存储折扣信息的字符串字段
    public bool isDiscount; // 存储是否有折扣的布尔字段

    public DiscountInfo(string discount, bool isDiscount)
    {
        this.discount = discount; // 使用提供的折扣信息初始化 discount 字段
        this.isDiscount = isDiscount; // 使用提供的是否有折扣信息初始化 isDiscount 字段
    }

    public void Deconstruct(out string dis, out bool isDis)
    {
        dis = this.discount; // 将 discount 字段的值分配给 dis 参数
        isDis = this.isDiscount; // 将 isDiscount 字段的值分配给 isDis 参数
    }
}


DiscountInfo info = new DiscountInfo("5折", true);
if (info is { discount: "6折", isDiscount: true }) print("信息相同");

public float GetMoney(DiscountInfo info, float money) => info switch
{
    { discount: "5折", isDiscount: true } => money * .5f,
    { discount: "6折", isDiscount: true } => money * .6f,
    { discount: "7折", isDiscount: true } => money * .7f,
    _ => money
};

print(GetMoney(info, 100));//50

元组模式

元组模式可以更简单的完成多个变量的判断,不需要声明数据结构类,可以直接利用元组进行判断。

举例:

int ii = 10;
bool bb = true;
if((ii, bb) is (11, true))
{
    print("元组的值相同");
}

public float GetMoney(string discount, bool isDiscount, float money) => (discount, isDiscount) switch
{
    ("5折", true) => money * .5f,
    ("6折", true) => money * .6f,
    ("7折", true) => money * .7f,
    _ => money
};

print(GetMoney("5折", true, 200));//100

位置模式

如果自定义类中实现了解构函数Deconstruct,可以使用位置模式。位置模式可以直接用对应类对象与元组进行is判断,不存在的解构函数Deconstruct会报错。

举例:


public class DiscountInfo
{
    public string discount; // 存储折扣信息的字符串字段
    public bool isDiscount; // 存储是否有折扣的布尔字段

    public DiscountInfo(string discount, bool isDiscount)
    {
        this.discount = discount; // 使用提供的折扣信息初始化 discount 字段
        this.isDiscount = isDiscount; // 使用提供的是否有折扣信息初始化 isDiscount 字段
    }

    public void Deconstruct(out string dis, out bool isDis)
    {
        dis = this.discount; // 将 discount 字段的值分配给 dis 参数
        isDis = this.isDiscount; // 将 isDiscount 字段的值分配给 isDis 参数
    }
}

if (info is ("5折", true))
{
    print("位置模式 满足条件");
}

public float GetMoney2(DiscountInfo info, float money) => info switch
{
    ("5折", true) when money > 100 => money * .5f,
    ("6折", true) => money * .6f,
    ("7折", true) => money * .7f,
    _ => money
};

public float GetMoney3(DiscountInfo info, float money) => info switch
{
    (string dis, bool isDis) when dis == "5折" && isDis => money * .5f,
    (string dis, bool isDis) when dis == "6折" && isDis => money * .6f,
    (string dis, bool isDis) when dis == "7折" && isDis => money * .7f,
    _ => money
};

print(GetMoney2(info, 300));

15.2 知识点代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

#region 知识点三 模式匹配增强功能——属性模式

public class DiscountInfo
{
    public string discount; // 存储折扣信息的字符串字段
    public bool isDiscount; // 存储是否有折扣的布尔字段

    public DiscountInfo(string discount, bool isDiscount)
    {
        this.discount = discount; // 使用提供的折扣信息初始化 discount 字段
        this.isDiscount = isDiscount; // 使用提供的是否有折扣信息初始化 isDiscount 字段
    }

    public void Deconstruct(out string dis, out bool isDis)
    {
        dis = this.discount; // 将 discount 字段的值分配给 dis 参数
        isDis = this.isDiscount; // 将 isDiscount 字段的值分配给 isDis 参数
    }
}


#endregion

public class Lesson15_CSharp各版本新功能和语法_CSharp8功能和语法_模式匹配增强 : MonoBehaviour
{

    void Start()
    {
        #region 知识点一 模式匹配回顾

        //模式匹配(Pattern Matching)
        //“模式匹配”是一种测试表达式是否具有特定特征的方法
        //在编程里指的是,把一个不知道具体数据信息的内容
        //通过一些固定的语法格式来确定模式数据的具体内容的过程

        //我们目前学习过的模式匹配

        //1.常量模式(is 常量):用于判断输入值是否等于某个值
        object o = 1.5f;
        if (o is 1)
        {
            print("o是1");
        }
        if (o is null)
        {
            print("o是null");
        }

        //2.类型模式(is 类型 变量名、case 类型 变量名):用于判断输入值类型,如果类型相同,将输入值提取出来
        //判断某一个变量是否是某一个类型,如果满足会将该变量存入你申明的变量中
        if (o is int i)
        {
            print(i);
        }
        switch (o)
        {
            case int value:
                print("int:" + value);
                break;
            case float value:
                print("float:" + value);
                break;
            case null:
                print("null");
                break;
            default:
                break;
        }

        //3.var模式:用于将输入值放入与输入值相同类型的新变量中
        //          相当于是将变量装入一个和自己类型一样的变量中
        if (o is var v)
        {
            print(v);
        }

        int GetInt()
        {
            return 1;
        }

        //以前写法
        int kk = GetInt();
        if(kk >= 0 && kk <= 10)
        {

        }

        //现在的写法
        if (GetInt() is var k && k >= 0 && k <= 10)
        {
            
        }
        #endregion

        #region 知识点二 模式匹配增强功能——switch表达式
        //switch表达式是对有返回值的switch语句的缩写
        //用=>表达式符号代替case:组合
        //用_弃元符号代替default
        //它的使用限制,主要是用于switch语句当中只有一句代码用于返回值时使用
        //语法:
        // 函数声明 => 变量 switch
        //{
        //常量=>返回值表达式,
        //常量=>返回值表达式,
        //常量=>返回值表达式,
        //....
        //_ => 返回值表达式,
        //}

        print(GetPos(PosType.Bottom_Right));
        #endregion

        #region 知识点三 模式匹配增强功能——属性模式

        //就是在常量模式的基础上判断对象上各属性
        //用法:变量 is {属性:值, 属性:值}

        DiscountInfo info = new DiscountInfo("5折", true);
        //if( info.discount == "6折" && info.isDiscount) print("信息相同");//以前的写法
        if (info is { discount: "6折", isDiscount: true }) print("信息相同");

        //它可以结合switch表达式使用
        //结合switch使用可以通过属性模式判断条件的组合

        print(GetMoney(info, 100));//50
        #endregion

        #region 知识点四 模式匹配增强功能——元组模式

        //通过刚才学习的 属性模式我们可以在switch表达式中判断多个变量同时满足再返回什么
        //但是它必须是一个数据结构类对象,判断其中的变量
        //而元组模式可以更简单的完成这样的功能,我们不需要声明数据结构类,可以直接利用元组进行判断

        //回顾
        int ii = 10;
        bool bb = true;
        if((ii, bb) is (11, true))
        {
            print("元组的值相同");
        }

        //举例说明
        print(GetMoney("5折", true, 200));//100
        #endregion

        #region 知识点五 模式匹配增强功能——位置模式

        //如果自定义类中实现了解构函数Deconstruct
        //那么我们可以直接用对应类对象与元组进行is判断
        //不存在的解构函数Deconstruct话会报错

        if (info is ("5折", true))
        {
            print("位置模式 满足条件");
        }

        //同样我们也可以配合switch表达式来处理逻辑
        //举例说明
        print(GetMoney2(info, 300));

        //补充:配合when关键字进行逻辑处理
        #endregion
    }

    #region 知识点三 模式匹配增强功能——属性模式
    public float GetMoney(DiscountInfo info, float money) => info switch
    {
        //可以利用属性模式 结合 switch表达式 判断n个条件是否满足
        { discount: "5折", isDiscount: true } => money * .5f,
        { discount: "6折", isDiscount: true } => money * .6f,
        { discount: "7折", isDiscount: true } => money * .7f,
        _ => money
    };

    #endregion

    #region 知识点五 模式匹配增强功能——位置模式

    public float GetMoney2(DiscountInfo info, float money) => info switch
    {
        ("5折", true) when money > 100 => money * .5f,
        ("6折", true) => money * .6f,
        ("7折", true) => money * .7f,
        _ => money
    };



    public float GetMoney3(DiscountInfo info, float money) => info switch
    {
        (string dis, bool isDis) when dis == "5折" && isDis => money * .5f,
        (string dis, bool isDis) when dis == "6折" && isDis => money * .6f,
        (string dis, bool isDis) when dis == "7折" && isDis => money * .7f,
        _ => money
    };

    #endregion

    #region 知识点四 模式匹配增强功能——元组模式

    public float GetMoney(string discount, bool isDiscount, float money) => (discount, isDiscount) switch
    {
        ("5折", true) => money * .5f,
        ("6折", true) => money * .6f,
        ("7折", true) => money * .7f,
        _ => money
    };

    #endregion

    #region 知识点二 模式匹配增强功能——switch表达式

    public Vector2 GetPos(PosType type) => type switch
    {
        PosType.Top_Left => new Vector2(0, 0),
        PosType.Top_Right => new Vector2(1, 0),
        PosType.Bottom_Left => new Vector2(0, 1),
        PosType.Bottom_Right => new Vector2(1, 1),
        _ => new Vector2(0, 0)
    };

    //之前的写法
    //public Vector2 GetPos(PosType type)
    //{
    //    switch (type)
    //    {
    //        case PosType.Top_Left:
    //            return new Vector2(0, 0);
    //        case PosType.Top_Right:
    //            return new Vector2(1, 0);
    //        case PosType.Bottom_Left:
    //            return new Vector2(0, 1);
    //        case PosType.Bottom_Right:
    //            return new Vector2(1, 1);
    //        default:
    //            return new Vector2(0, 0);
    //    }
    //}

    #endregion

}

#region 知识点二 模式匹配增强功能——switch表达式

public enum PosType
{
    Top_Left,
    Top_Right,
    Bottom_Left,
    Bottom_Right,
}


#endregion


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏