C# 8.0属性模式 (Property Patterns)

在C# 8.0及更高版本中,属性模式使得代码更加简洁和易读,因为它允许你在一个表达式中同时检查对象的类型和它的属性。这减少了需要编写的代码量,并提高了代码的可维护性。

属性模式可以在多种场景下使用,包括但不限于:

1、数据验证:在对象的状态需要根据其属性值进行验证时。

2、业务逻辑:在根据对象的不同属性值执行不同的业务逻辑时。

3、状态机:在基于对象状态的复杂逻辑中,根据对象的属性决定状态转移。

4、UI逻辑:在UI编程中,根据数据对象的属性来决定显示逻辑。

使用属性模式进行数据验证

csharp 复制代码
public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

public static class PersonValidator
{
    public static bool IsValid(Person person) =>
        person switch
        {
            { Age: < 0 } => false, // Age不能为负数
            { Age: > 120 } => false, // Age不能超过120岁
            { Name: null } => false, // Name不能为空
            _ => true
        };
}

class Program
{
    static void Main()
    {
        var person = new Person { Name = "Alice", Age = 130 };
        Console.WriteLine(PersonValidator.IsValid(person)); // 输出: True
    }
}

在这个例子中,PersonValidator类使用属性模式来验证Person对象是否有效。它检查Age属性是否在合理范围内,以及Name属性是否非空。

基于属性值执行业务逻辑

csharp 复制代码
public class Order
{
    public decimal Amount { get; set; }
    public bool IsPriority { get; set; }
}

public static class ShippingCalculator
{
    public static decimal CalculateShipping(Order order) =>
        order switch
        {
            { IsPriority: true } => 0, // 优先订单免运费
            { Amount: > 100 } => 0, // 订单金额超过100免运费
            _ => 5 // 默认运费
        };
}

class Program
{
    static void Main()
    {
        var order = new Order { Amount = 80, IsPriority = false };
        Console.WriteLine(ShippingCalculator.CalculateShipping(order)); // 输出: 5
    }
}

在这个例子中,ShippingCalculator类使用属性模式来计算订单的运费。它根据订单是否是优先订单以及订单金额来决定运费。

UI逻辑中的属性模式

csharp 复制代码
public class Product
{
    public string Category { get; set; }
    public int Stock { get; set; }
}

public static class ProductDisplay
{
    public static string GetDisplayStatus(Product product) =>
        product switch
        {
            { Stock: 0 } => "Sold Out",
            { Category: "New" } => "New Arrival",
            { Stock: <= 5 } => "Low Stock",
            _ => "Available"
        };
}

class Program
{
    static void Main()
    {
        var product = new Product { Category = "Electronics", Stock = 20 };
        Console.WriteLine(ProductDisplay.GetDisplayStatus(product)); // 输出: Available
    }
}

在这个例子中,ProductDisplay类使用属性模式来决定产品的显示状态。根据库存量和类别,它会返回不同的状态字符串。

使用属性模式匹配嵌套对象

假设我们有一个订单系统,其中包含Customer对象和Order对象,Order对象中有一个Customer属性。我们希望根据订单的金额以及订单所属客户的会员等级来决定折扣。

csharp 复制代码
public class Customer
{
    public string Name { get; set; }
    public string MembershipLevel { get; set; } // 例如 "Gold", "Silver", "Bronze"
}

public class Order
{
    public Customer Customer { get; set; }
    public decimal Amount { get; set; }
}

public static class DiscountCalculator
{
    public static decimal CalculateDiscount(Order order) =>
        order switch
        {
            // 会员等级为Gold,并且订单金额超过1000的订单,折扣为15%
            { Customer: { MembershipLevel: "Gold" }, Amount: > 1000 } => 0.15m,
            // 会员等级为Silver,并且订单金额超过500的订单,折扣为10%
            { Customer: { MembershipLevel: "Silver" }, Amount: > 500 } => 0.10m,
            // 其他情况,默认不提供折扣
            _ => 0m
        };
}

class Program
{
    static void Main()
    {
        var customer = new Customer { Name = "Alice", MembershipLevel = "Gold" };
        var order = new Order { Customer = customer, Amount = 1200 };
        Console.WriteLine($"Discount: {DiscountCalculator.CalculateDiscount(order):P}"); // 输出: Discount: 15.00%
    }
}

在这个例子中,DiscountCalculator类使用属性模式来计算订单的折扣。它检查订单的Customer属性的MembershipLevel字段以及Amount字段来决定折扣百分比。

通过组合属性模式,我们可以在一个switch表达式中同时匹配多个属性,这使得我们能够编写出更加强大和灵活的条件逻辑。这种模式的组合使用提高了代码的可读性和维护性,特别是在处理复杂的业务规则时。

Ref

相关推荐
慧都小妮子4 分钟前
MSG 附件太占内存?Aspose.Email for .NET 26.9 延迟加载
c#·.net·aspose·内存优化·延迟加载·aspose.email·附件内存
for_ever_love__7 分钟前
LangChain Token 计数与成本控制:先知道钱花在哪
开发语言·langchain
m0_547486668 分钟前
《数据结构 (C语言)》期末试卷及答案(10套)2026版
c语言·开发语言·数据结构
Sand(ContextGate)11 分钟前
从开发者调试工具到消费级 App:一个 AI 电商导购项目的 C 端改造与 6 个连环踩坑实录
开发语言·人工智能·python·ai·langchain
白杨尚青16 分钟前
C++入门篇(十七):priority_queue 完整模拟实现——仿函数、区间建堆与指针特化(附完整代码仓库)
开发语言·c++·stl·仿函数
慧都小妮子24 分钟前
FastReport PDF/UA 导出:让出海 PDF 满足无障碍合规要求
pdf·c#·fastreport·报表导出·pdf/ua·pdf 无障碍
mx_jun25 分钟前
Wireshark 蓝牙 HCI 日志分析常用操作速查
windows·microsoft·hci·bt
逐光者93330 分钟前
滤波器的 R 与 C 如何选择:从截止频率到工程实践
c语言·开发语言·r语言
Eider199835 分钟前
大模型输出格式幻觉解决思路
开发语言·前端·javascript
艾iYYY42 分钟前
思考: C++ 万能引用与完美转发
c++·windows·microsoft