• [译]C#7 Pattern Matching


    原文

    public struct Square
    {
        public double Side { get; }
    
        public Square(double side)
        {
            Side = side;
        }
    }
    public struct Circle
    {
        public double Radius { get; }
    
        public Circle(double radius)
        {
            Radius = radius;
        }
    }
    public struct Rectangle
    {
        public double Length { get; }
        public double Height { get; }
    
        public Rectangle(double length, double height)
        {
            Length = length;
            Height = height;
        }
    }
    public struct Triangle
    {
        public double Base { get; }
        public double Height { get; }
    
        public Triangle(double @base, double height)
        {
            Base = @base;
            Height = height;
        }
    }
    

    下面分别使用7之前的语法和7来写一个计算形状面积的方法。

    is 类型模式表达式

    在C# 7.0之前,我们需要使用ifis语句去判断类别:

    public static double ComputeArea(object shape)
    {
        if (shape is Square)
        {
            var s = (Square)shape;
            return s.Side * s.Side;
        } 
        else if (shape is Circle)
        {
            var c = (Circle)shape;
            return c.Radius * c.Radius * Math.PI;
        }
        // elided
        throw new ArgumentException(
            message: "shape is not a recognized shape",
            paramName: nameof(shape));
    }
    

    在C# 7.0 中,通过使用is表达式的扩展可以在类型判断成功的时候将其分配给一个变量,从而简化上面的代码:

    public static double ComputeAreaModernIs(object shape)
    {
        if (shape is Square s)
            return s.Side * s.Side;  // s 只在这可用
        else if (shape is Circle c)
            return c.Radius * c.Radius * Math.PI;   // c 只在这可用
        else if (shape is Rectangle r)
            return r.Height * r.Length;    // r 只在这可用
        // elided
        throw new ArgumentException(
            message: "shape is not a recognized shape",
            paramName: nameof(shape));
    }
    

    新的is表达式对值类型和引用类型都好使。

    上面的例子中,变量scr只有在模式匹配表达式为true的时候才作用被分配。

    通过switch语句使用模式匹配

    之前switch只支持常量模式。只能将变量和case中的常量进行比较:

    public static string GenerateMessage(params string[] parts)
    {
        switch (parts.Length)
        {
            case 0:
                return "No elements to the input";
            case 1:
                return $"One element: {parts[0]}";
            case 2:
                return $"Two elements: {parts[0]}, {parts[1]}";
            default:
                return $"Many elements. Too many to write";
        }
    }
    

    7之前switch只支持常量模式。在C# 7.0 中没有这个限制了,可以通过switch来使用类型模式:

    public static double ComputeAreaModernSwitch(object shape)
    {
        switch (shape)
        {
            case Square s:
                return s.Side * s.Side;
            case Circle c:
                return c.Radius * c.Radius * Math.PI;
            case Rectangle r:
                return r.Height * r.Length;
            default:
                throw new ArgumentException(
                    message: "shape is not a recognized shape",
                    paramName: nameof(shape));
        }
    }
    

    case表达式中使用when

    public static double ComputeArea_Version3(object shape)
    {
        switch (shape)
        {
            case Square s when s.Side == 0:
            case Circle c when c.Radius == 0:
                return 0;
    
            case Square s:
                return s.Side * s.Side;
            case Circle c:
                return c.Radius * c.Radius * Math.PI;
            default:
                throw new ArgumentException(
                    message: "shape is not a recognized shape",
                    paramName: nameof(shape));
        }
    }
    

    case表达式中声明变量

    static object CreateShape(string shapeDescription)
    {
        switch (shapeDescription)
        {
            case "circle":
                return new Circle(2);
    
            case "square":
                return new Square(4);
            
            case "large-circle":
                return new Circle(12);
    
            case var o when (o?.Trim()?.Length ?? 0) == 0:
                // white space
                return null;
            default:
                return "invalid shape description";
        }            
    }
    
  • 相关阅读:
    (二)使用log4net写入数据库自定义日志
    (一)使用log4net生成日志文件
    微信公众号测试号内网配置以及微信网页授权
    ios浏览器调试踩坑(1)----mescroll.js和vue-scroller
    three 3D实例学习
    golang解析git log时间
    Shell 简易教程
    golang 并发程序写入map两种实现方式sync.Mutex和chan的效率对比
    golang字符串string与字符数组[]byte高效转换
    mysql begin rollback commit 事务互斥验证
  • 原文地址:https://www.cnblogs.com/irocker/p/pattern-matching.html
Copyright © 2020-2023  润新知