C# 8.0的新功能二:简化多属性匹配的if语句

211 阅读2分钟

之前,我们研究了switch开关表达式,在开关表达式的基础上,c# 8 还引入了属性模式匹配的概念,这有助于我们简化在类属性上的多if语句。

1、一个例子

例如,假设我们有一个CustomerOrder:

class CustomerOrder
{
    public string State { get; set; }
    public bool IsVipMember { get; set; }
    // etc.
}

我们创建了一个这样的实例:

var order1 = new CustomerOrder
{
    State = "WA",
    IsVipMember = false
};

现在说我们想根据订单要交付到哪个省来计算交付成本。如果客户是VIP会员,则根据省的具体情况,可以免收送货费。我们可以使用if … else if来编写:

if (order1.State == "WA" && order1.IsVipMember)
{
    deliveryCost = 0M;
}
else if (order1.State == "WA" && !order1.IsVipMember)
{
    deliveryCost = 2.3M;
}
else if (order1.State == "NT" && !order1.IsVipMember)
{
    deliveryCost = 4.1M;
}
else
{
    deliveryCost = 5M;
}

如果逻辑复杂,前面的代码将变得更大,更难于读取我们添加的更多状态。

2、使用switch 语句替换

一种替代方法是使用switch语句尝试简化此操作:

decimal deliveryCost;
 
switch (order1.State, order1.IsVipMember)
{
    case ("WA", true):
        deliveryCost = 0M;
            break;
    case ("WA", false):
        deliveryCost = 2.3M;
        break;
    case ("NT", false):
        deliveryCost = 4.1M;
        break;
    default:
        deliveryCost = 5M;
        break;
}

3、极简模式,switch表达式

在前面的代码中,所有case块仍有一些“复杂格式”。我们可以改用使用属性模式匹配的switch表达式:

deliveryCost = order1 switch
{
    { State: "WA", IsVipMember: true } => 0M,
    { State: "WA", IsVipMember: false } => 2.3M,
    { State: "NT", IsVipMember: false } => 4.1M,
    _ => 5M
};

请注意,前面的代码简明扼要,并且很容易看到所有情况和组合。

如果在某些国家,VIP身份与计算交付成本无关,该怎么办?
假设状态“ QE”始终具有很高的交付成本,即使对于VIP来说也从未降低:

deliveryCost = order1 switch
{
    { State: "WA", IsVipMember: true } => 0M,
    { State: "WA", IsVipMember: false } => 2.3M,
    { State: "NT", IsVipMember: false } => 4.1M,
    { State: "QE"} => 99.99M,
    _ => 5M
};

在前面的代码中,如果“状态”为“ QE”,则交货成本为99.99。还要注意使用丢弃物_,它表示“对于上面未列出的所有其他组合,将交付成本设置为5”。

4、小结

有关c#8的知识,你学到了吗? 关注我,学习不迷路,我会及时更新有关学习的心得和体会,一键三连是非常受欢迎的,来吧,行动起来。