331.C# 屬性模式 (Property Patterns)

2024年2月6日 20点热度 0人点赞

摘要


屬性模式是C# 8.0中引入的一種新的模式匹配功能。它允許你根據對象的屬性或字段進行模式匹配,這使得代碼更加簡潔和直觀。屬性模式特別適用於解構復雜對象,並基於這些對象的屬性值進行條件判斷。

正文


應用場景

屬性模式可以在多種場景下使用,包括但不限於:

  1. 數據驗證:在對象的狀態需要根據其屬性值進行驗證時。
  2. 業務邏輯:在根據對象的不同屬性值執行不同的業務邏輯時。
  3. 狀態機:在基於對象狀態的復雜邏輯中,根據對象的屬性決定狀態轉移。
  4. UI邏輯:在UI編程中,根據數據對象的屬性來決定顯示邏輯。

例子 1: 使用屬性模式進行數據驗證

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屬性是否非空。

例子 2: 基於屬性值執行業務邏輯

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類使用屬性模式來計算訂單的運費。它根據訂單是否是優先訂單以及訂單金額來決定運費。

例子 3: UI邏輯中的屬性模式

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類使用屬性模式來決定產品的顯示狀態。根據庫存量和類別,它會返回不同的狀態字符串。

例子4: 使用屬性模式匹配嵌套對象

假設我們有一個訂單系統,其中包含Customer對象和Order對象,Order對象中有一個Customer屬性。我們希望根據訂單的金額以及訂單所屬客戶的會員等級來決定折扣。

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表達式中同時匹配多個屬性,這使得我們能夠編寫出更加強大和靈活的條件邏輯。這種模式的組合使用提高了代碼的可讀性和維護性,特別是在處理復雜的業務規則時。

結論

C#的屬性模式為代碼提供了一種強大的模式匹配工具,它可以簡化條件邏輯並提高代碼的可讀性。通過直接在switch表達式中訪問對象的屬性,可以更容易地編寫條件分支,從而使代碼更加整潔。這些例子展示了屬性模式在實際應用中的靈活性和實用性。開發者可以根據自己的需求,將屬性模式應用到各種不同的場景中,以提高代碼的表達力和效率。