Skip to content

Instantly share code, notes, and snippets.

@mirmostafa
Last active September 11, 2024 09:53
Show Gist options
  • Save mirmostafa/1bd200550b4d3b34720c5fe0ea233baa to your computer and use it in GitHub Desktop.
Save mirmostafa/1bd200550b4d3b34720c5fe0ea233baa to your computer and use it in GitHub Desktop.
Pattern Matching in C# 12

بهبودهای جدید در Pattern Matching در C# 12

مطابقت با الگوها (Pattern Matching) از نسخه C# 7 معرفی شد و در هر نسخه بعدی بهبود یافته است. در C# 12، امکانات جدیدی به Pattern Matching اضافه شده که امکان نوشتن کدهای خواناتر و قدرتمندتر را فراهم می‌کند. در اینجا به برخی از بهبودهای کلیدی می‌پردازیم:

1. Extended List Patterns

در C# 12، الگوهای لیستی (List Patterns) گسترش یافته‌اند تا با مجموعه‌های پیچیده‌تر مانند آرایه‌ها، List<T> و سایر انواع مجموعه‌ها مطابقت پیدا کنند. الگوهای لیستی به شما اجازه می‌دهند تا از عملیات‌هایی مانند چک کردن وجود عناصر در یک لیست یا انجام عملیات‌های مختلف روی آن‌ها به شکلی تمیز و قابل‌خواندن استفاده کنید.

مثال:
int[] numbers = { 1, 2, 3, 4, 5 };

// استفاده از الگوی لیستی برای مطابقت با آرایه‌ای که اولین و آخرین عنصرش مشخص است
if (numbers is [1, .., 5])
{
    Console.WriteLine("The array starts with 1 and ends with 5.");
}

// استفاده از الگوی لیستی برای مطابقت با آرایه‌ای با دو عنصر یا بیشتر
if (numbers is [var first, .., var last])
{
    Console.WriteLine($"First element: {first}, Last element: {last}");
}

در مثال بالا:

  • [1, .., 5] یک الگوی لیستی است که بررسی می‌کند آیا آرایه با ۱ شروع و با ۵ پایان می‌یابد یا خیر.
  • [var first, .., var last] یک الگوی لیستی است که اولین و آخرین عنصر آرایه را استخراج می‌کند.

2. Pattern Combinators (and, or, not) Enhancements

در C# 12، ترکیب‌کننده‌های الگو (Pattern Combinators) بهبود یافته‌اند. این ترکیب‌کننده‌ها شامل and، or و not هستند که به شما امکان می‌دهند الگوهای پیچیده‌تر و انعطاف‌پذیرتری بسازید.

مثال:
object data = new[] { 1, 2, 3 };

if (data is int[] { Length: > 0 } and [1, ..])
{
    Console.WriteLine("Data is a non-empty integer array starting with 1.");
}

if (data is not null or string)
{
    Console.WriteLine("Data is not null and is not a string.");
}

در این مثال:

  • and برای ترکیب دو الگوی شرطی استفاده می‌شود: آرایه‌ای با حداقل یک عنصر که با 1 شروع می‌شود.
  • not برای مطابقت با هر داده‌ای که null یا string نیست.

3. Relational Patterns Enhancements

در نسخه‌های قبلی C#، الگوهای رابطه‌ای (Relational Patterns) برای مقایسه مقادیر با یک عدد ثابت ارائه شد. در C# 12، می‌توانید از این الگوها به طور انعطاف‌پذیرتری در ترکیب با سایر الگوها استفاده کنید.

مثال:
int number = 42;

if (number is > 0 and < 100)
{
    Console.WriteLine("Number is between 1 and 99.");
}

if (number is >= 50 or <= 10)
{
    Console.WriteLine("Number is 10 or less, or 50 or greater.");
}

در اینجا:

  • از and و or برای ترکیب چندین الگوی رابطه‌ای استفاده شده است.

4. Recursive Patterns Enhancements

C# 12 پشتیبانی از الگوهای بازگشتی (Recursive Patterns) را بهبود داده است. این الگوها به شما اجازه می‌دهند تا ساختارهای داده‌های تو در تو را به شکل موثرتری بررسی کنید.

مثال:
class Node
{
    public int Value { get; set; }
    public Node? Left { get; set; }
    public Node? Right { get; set; }
}

Node tree = new Node
{
    Value = 5,
    Left = new Node { Value = 3 },
    Right = new Node { Value = 8 }
};

// الگوی بازگشتی برای مطابقت با ساختار درختی
if (tree is { Value: 5, Left: { Value: 3 }, Right: { Value: 8 } })
{
    Console.WriteLine("Tree matches the pattern.");
}

در این مثال:

  • از یک الگوی بازگشتی برای بررسی ساختار یک درخت دودویی استفاده شده است.

نتیجه‌گیری

بهبودهای جدید در Pattern Matching در C# 12 امکان نوشتن کدهای تمیزتر، خواناتر، و قابل فهم‌تر را فراهم کرده است. این ویژگی‌ها به ویژه در زمانی که با ساختارهای داده پیچیده یا منطق‌های پیچیده‌ای سروکار دارید، بسیار مفید خواهند بود.

public class ErrorInfo
{
public string ErrorType { get; set; } = string.Empty; // Database, File, Api
public int ErrorCode { get; set; } // Error code specific to the type
}
public void HandleError(ErrorInfo error)
{
switch (error)
{
case { ErrorType: "Database", ErrorCode: > 500 }:
Console.WriteLine("Critical database error occurred!");
// کد برای ارسال هشدار به تیم پشتیبانی
break;
case { ErrorType: "File", ErrorCode: 404 }:
Console.WriteLine("File not found. Please check the file path.");
// کد برای اطلاع به کاربر
break;
case { ErrorType: "Api", ErrorCode: >= 400 and < 500 }:
Console.WriteLine("Client error occurred while calling the API.");
// کد برای لاگ‌گذاری خطای سمت مشتری
break;
case { ErrorType: "Api", ErrorCode: >= 500 }:
Console.WriteLine("Server error occurred while calling the API.");
// کد برای لاگ‌گذاری خطای سمت سرور
break;
case { ErrorType: var type, ErrorCode: var code }:
Console.WriteLine($"Unhandled error type: {type} with code: {code}");
// کد برای مدیریت خطاهای ناشناخته
break;
}
}
public class Transaction
{
public string TransactionType { get; set; } = string.Empty; // Payment, Withdrawal, Transfer
public decimal Amount { get; set; }
}
public void ProcessTransaction(Transaction transaction)
{
switch (transaction)
{
case { TransactionType: "Payment", Amount: > 0 }:
Console.WriteLine("Processing payment...");
// کد برای پردازش پرداخت
break;
case { TransactionType: "Withdrawal", Amount: > 0 }:
Console.WriteLine("Processing withdrawal...");
// کد برای پردازش برداشت
break;
case { TransactionType: "Transfer", Amount: > 0 }:
Console.WriteLine("Processing transfer...");
// کد برای پردازش انتقال
break;
case { Amount: <= 0 }:
Console.WriteLine("Invalid transaction amount.");
// کد برای مدیریت تراکنش‌های نامعتبر
break;
default:
Console.WriteLine("Unknown transaction type.");
// کد برای مدیریت تراکنش‌های ناشناخته
break;
}
}
public class ApiRequest
{
public string Operation { get; set; } = string.Empty; // Create, Update, Delete, Fetch
public string Resource { get; set; } = string.Empty; // Product, User, Order
}
public void HandleRequest(ApiRequest request)
{
// استفاده از Pattern Matching برای مدیریت درخواست‌ها
switch (request)
{
case { Operation: "Create", Resource: "Product" }:
Console.WriteLine("Creating a new product...");
// کد مربوط به ایجاد محصول
break;
case { Operation: "Update", Resource: "User" }:
Console.WriteLine("Updating user details...");
// کد مربوط به بروزرسانی اطلاعات کاربر
break;
case { Operation: "Delete", Resource: "Order" }:
Console.WriteLine("Deleting an order...");
// کد مربوط به حذف سفارش
break;
case { Operation: "Fetch", Resource: var resource } when resource is "Product" or "User" or "Order":
Console.WriteLine($"Fetching {resource} details...");
// کد مربوط به دریافت جزئیات
break;
case { Operation: var op, Resource: var res } when op is not ("Create" or "Update" or "Delete" or "Fetch"):
Console.WriteLine($"Invalid operation: {op} for resource: {res}");
break;
default:
Console.WriteLine("Invalid request.");
break;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment