跳至頁尾內容
.NET 幫助

C# 模式匹配表達式(開發者如何理解其工作原理)

C# 中的模式匹配是一項強大的功能,它在 C# 7.0 中引入,並在隨後的版本中擴展了。 它允許開發人員在處理條件語句、類型檢查和物件解構時編寫更簡潔、更具表現力的程式碼。

模式匹配表達式提供了一種靈活直觀的方式,可以將值與模式進行匹配並執行相應的程式碼區塊。 本文將探討 C# 中模式比對表達式的複雜性,包括語法、使用案例和程式碼範例。 在文章的最後,我們還將探討Iron SoftwareIronPDF PDF 生成庫,以便在 C# 應用程式中動態生成 PDF 文件。

C# 中模式匹配的優勢

C# 程式碼中的模式匹配具有諸多優勢:

-增強可讀性:模式匹配簡化了複雜的條件邏輯,使您的程式碼更容易被自己和其他開發人員理解和遵循。 -減少程式碼行數:透過將複雜的條件語句簡化為簡潔的模式,模式匹配有助於簡化程式碼庫,從而減少程式碼行數並實現更簡潔的實作。 -提高可維護性:模式匹配帶來的清晰性有助於更輕鬆地進行程式碼維護和偵錯。 模式明確劃分後,就可以更輕鬆地根據需要識別和修改特定的邏輯區塊,而不會影響程式碼庫的其餘部分。 -更具表現力的演算法:模式匹配使開發人員能夠以更自然、更直觀的方式表達演算法。 透過將程式碼結構與問題解決範式相匹配,模式匹配有助於創建與其概念模型非常相似的演算法。

C# 中的模式匹配類型

以下表達式支援模式匹配:

  • is表達式
  • switch語句
  • switch表達式

可以使用以下模式與這些結構進行比對:

聲明和類型模式

在 C# 中,宣告模式和類型模式是檢查表達式執行時間類型與給定類型相容性的重要工具。借助聲明模式,您可以同時檢查相容性並聲明新的局部變數。 請看以下範例:

object greeting = "Iron Software is Awesome!";
if (greeting is string message)
{
    Console.WriteLine(message.ToLower());  // output: iron software is awesome!
}
object greeting = "Iron Software is Awesome!";
if (greeting is string message)
{
    Console.WriteLine(message.ToLower());  // output: iron software is awesome!
}
$vbLabelText   $csharpLabel

在這裡,聲明模式確保如果表達式greetingstring類型匹配,則將其賦值給變數message ,從而啟用後續操作。

當下列任一條件成立時,聲明模式即成立:

  • 此表達式的運行時類型為T
  • 表達式的運行時類型派生自T ,實作了介面T ,或者可以隱式轉換為T
  • 此表達式的運行時類型是可為空的值類型,其底層類型為T
  • 存在從表達式的運行時類型到類型T裝箱或拆箱轉換。

以下範例說明了上述條件:

int? nullableX = 8;
int y = 45;
object boxedy = y;
if (nullableX is int a && boxedy is int b)
{
    Console.WriteLine(a + b);  // output: 53
}
int? nullableX = 8;
int y = 45;
object boxedy = y;
if (nullableX is int a && boxedy is int b)
{
    Console.WriteLine(a + b);  // output: 53
}
$vbLabelText   $csharpLabel

在這裡, nullableX符合模式,因為它是一個可空值類型,其底層類型為intboxedy符合模式,因為它可以拆箱為int

當您只需要檢查表達式的類型而無需聲明新變數時,可以使用 discard _ ,如下例所示:

public static decimal CalculateToll(Vehicle vehicle) => vehicle switch
{
    Bus _ => 4.00m,
    Motor _ => 8.50m,
    null => throw new ArgumentNullException(nameof(vehicle)),
    _ => throw new ArgumentException("Unknown type of a vehicle", nameof(vehicle)),
};
public static decimal CalculateToll(Vehicle vehicle) => vehicle switch
{
    Bus _ => 4.00m,
    Motor _ => 8.50m,
    null => throw new ArgumentNullException(nameof(vehicle)),
    _ => throw new ArgumentException("Unknown type of a vehicle", nameof(vehicle)),
};
$vbLabelText   $csharpLabel

在此程式碼片段中, _用作任何與Vehicle相符的類型佔位符。

聲明模式和類型模式都能確保表達式在模式匹配之前不為空。 您可以使用取反的空常數模式來檢查是否為非空值,如下所示:

if (inputVal is not null)
{
    // ...
}
if (inputVal is not null)
{
    // ...
}
$vbLabelText   $csharpLabel

此否定操作確保在進行後續操作之前inputVal不為空。

透過在 C# 程式碼中利用聲明和類型模式,您可以提高程式碼的可讀性,減少程式碼行數,並更有效地表達演算法。 這些模式提供了一種簡潔而富有表現力的方式來處理基於類型的邏輯,並提高程式碼庫的可維護性。

恆定模式

常量模式用於驗證表達式的結果是否與特定的常數值相符。 請看以下範例:

public static decimal GetGroupTicketPrice(int visitorCount) => visitorCount switch
{
    1 => 2.0m,
    2 => 10.0m,
    3 => 25.0m,
    4 => 60.0m,
    0 => 0.0m,
    _ => throw new ArgumentException($"Not supported number of visitors: {visitorCount}", nameof(visitorCount)),
};
public static decimal GetGroupTicketPrice(int visitorCount) => visitorCount switch
{
    1 => 2.0m,
    2 => 10.0m,
    3 => 25.0m,
    4 => 60.0m,
    0 => 0.0m,
    _ => throw new ArgumentException($"Not supported number of visitors: {visitorCount}", nameof(visitorCount)),
};
$vbLabelText   $csharpLabel

在這裡,常數模式會檢查visitorCount是否與任何指定的常數值匹配,並傳回相應的票價。

在固定的模式中,您可以使用各種類型的常數表達式,例如:

  1. 整數或浮點數值字面量。
  2. 角色。
  3. 字串字面量。
  4. 布林值( truefalse )。
  5. 枚舉值。
  6. 已宣告的常數欄位或局部變數的名稱。
  7. null

Span<char>類型的表達式Span<char>ReadOnlySpan<char>可以匹配常數字串。

若要檢查是否為null ,請使用如下所示的常數模式:

if (inputVal is null)
{
    return;
}
if (inputVal is null)
{
    return;
}
$vbLabelText   $csharpLabel

這裡,該模式確保在進行進一步操作之前inputVal為空。

您也可以使用取反的空常數模式來確定非空值:

if (inputVal is not null)
{
    // ...
}
if (inputVal is not null)
{
    // ...
}
$vbLabelText   $csharpLabel

此模式驗證inputVal是否不為空,因此可以安全地執行後續操作。

透過在 C# 程式碼中加入常數模式,可以有效處理需要匹配特定常數值的場景,從而提高程式碼的清晰度和可維護性。

關係模式

關係模式提供了一種將表達式結果與常數進行比較的方法。 請看以下範例:

Console.WriteLine(Classify(20));  // output: Too high
Console.WriteLine(Classify(double.NaN));  // output: Unknown
Console.WriteLine(Classify(4));  // output: Acceptable

static string Classify(double measurement) => measurement switch
{
    < -4.0 => "Too low",
    > 10.0 => "Too high",
    double.NaN => "Unknown",
    _ => "Acceptable",
};
Console.WriteLine(Classify(20));  // output: Too high
Console.WriteLine(Classify(double.NaN));  // output: Unknown
Console.WriteLine(Classify(4));  // output: Acceptable

static string Classify(double measurement) => measurement switch
{
    < -4.0 => "Too low",
    > 10.0 => "Too high",
    double.NaN => "Unknown",
    _ => "Acceptable",
};
$vbLabelText   $csharpLabel

在這裡,關係模式將measurement與特定閾值進行比較,以確定其分類。

關係模式的右側部分必須是常數表達式,可以是整數、浮點數、 charenum類型。 &lt;&gt;&lt;=&gt;=運算子可以用在左邊。

若要使表達式結果在特定範圍內匹配,請使用連接"and"模式,如下所示:

Console.WriteLine(GetCalendarSeason(new DateTime(2024, 3, 12)));  // output: spring
Console.WriteLine(GetCalendarSeason(new DateTime(2024, 7, 12)));  // output: summer
Console.WriteLine(GetCalendarSeason(new DateTime(2024, 2, 12)));  // output: winter

static string GetCalendarSeason(DateTime date) => date.Month switch
{
    >= 3 and < 6 => "spring",
    >= 6 and < 9 => "summer",
    >= 9 and < 12 => "autumn",
    12 or (>= 1 and <3) => "winter",
    _ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."),
};
Console.WriteLine(GetCalendarSeason(new DateTime(2024, 3, 12)));  // output: spring
Console.WriteLine(GetCalendarSeason(new DateTime(2024, 7, 12)));  // output: summer
Console.WriteLine(GetCalendarSeason(new DateTime(2024, 2, 12)));  // output: winter

static string GetCalendarSeason(DateTime date) => date.Month switch
{
    >= 3 and < 6 => "spring",
    >= 6 and < 9 => "summer",
    >= 9 and < 12 => "autumn",
    12 or (>= 1 and <3) => "winter",
    _ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."),
};
$vbLabelText   $csharpLabel

這段摘錄描述如何利用連接詞"and"模式,根據月份落在特定範圍內來確定日曆季節。 它還提到,關係模式提供了一種簡潔而富有表現力的手段,可以將表達式的結果與常數進行比較,從而提高程式碼的清晰度和可維護性。

丟棄模式

丟棄模式(以_表示)用於匹配任何表達式,包括null 。 舉例來說:

Console.WriteLine(GetDiscountInPercent(DayOfWeek.Friday));  // output: 5.0
Console.WriteLine(GetDiscountInPercent(null));  // output: 0.0
Console.WriteLine(GetDiscountInPercent((DayOfWeek)10));  // output: 0.0

static decimal GetDiscountInPercent(DayOfWeek? dayOfWeek) => dayOfWeek switch
{
    DayOfWeek.Monday => 0.5m,
    DayOfWeek.Tuesday => 12.5m,
    DayOfWeek.Wednesday => 7.5m,
    DayOfWeek.Thursday => 12.5m,
    DayOfWeek.Friday => 5.0m,
    DayOfWeek.Saturday => 2.5m,
    DayOfWeek.Sunday => 2.0m,
    _ => 0.0m,
};
Console.WriteLine(GetDiscountInPercent(DayOfWeek.Friday));  // output: 5.0
Console.WriteLine(GetDiscountInPercent(null));  // output: 0.0
Console.WriteLine(GetDiscountInPercent((DayOfWeek)10));  // output: 0.0

static decimal GetDiscountInPercent(DayOfWeek? dayOfWeek) => dayOfWeek switch
{
    DayOfWeek.Monday => 0.5m,
    DayOfWeek.Tuesday => 12.5m,
    DayOfWeek.Wednesday => 7.5m,
    DayOfWeek.Thursday => 12.5m,
    DayOfWeek.Friday => 5.0m,
    DayOfWeek.Saturday => 2.5m,
    DayOfWeek.Sunday => 2.0m,
    _ => 0.0m,
};
$vbLabelText   $csharpLabel

在上面的丟棄模式範例中,它處理所有可能的輸入值。 一周中的每一天都已設定好,並提供了預設值。 這樣一來,所有可能的值都得到了處理。 丟棄模式不能用作is表達式或switch語句中的模式。 在這種情況下,可以使用var模式和丟棄符號,例如var _ ,來匹配任何表達式。 但是,在switch表達式中允許使用丟棄模式。 更多詳情請參閱功能提案說明中的"丟棄模式"部分。

邏輯模式

C# 中的邏輯模式提供了強大的模式匹配工具,包括否定、合取和析取,從而可以實現更靈活、更具表現力的匹配條件。

否定( not模式)

否定模式(以not表示)與表達式匹配,當被否定的模式與表達式不匹配時,模式才會與表達式匹配。 這對於檢查表達式是否非空尤其有用,如下所示:

if (input is not null)
{
    // ...
}
if (input is not null)
{
    // ...
}
$vbLabelText   $csharpLabel

這裡,如果input不為空,則執行該程式碼區塊。

連接( and模式)

使用and關鍵字的合取模式,當兩個模式都與表達式相符時,表達式才會相符。 這樣就可以組合多個條件,如下例所示:

Console.WriteLine(Classify(13));    // output: High
Console.WriteLine(Classify(-100));  // output: Too low
Console.WriteLine(Classify(5.7));   // output: Acceptable

static string Classify(double measurement) => measurement switch
{
    < -40.0 => "Too low",
    >= -40.0 and < 0 => "Low",
    >= 0 and < 10.0 => "Acceptable",
    >= 10.0 and < 20.0 => "High",
    >= 20.0 => "Too high",
    double.NaN => "Unknown",
};
Console.WriteLine(Classify(13));    // output: High
Console.WriteLine(Classify(-100));  // output: Too low
Console.WriteLine(Classify(5.7));   // output: Acceptable

static string Classify(double measurement) => measurement switch
{
    < -40.0 => "Too low",
    >= -40.0 and < 0 => "Low",
    >= 0 and < 10.0 => "Acceptable",
    >= 10.0 and < 20.0 => "High",
    >= 20.0 => "Too high",
    double.NaN => "Unknown",
};
$vbLabelText   $csharpLabel

在這個例子中, measurement是根據其值範圍進行分類的。

析取( or模式)

使用or關鍵字的析取模式,當任一模式與表達式相符時,該表達式就會相符。 這樣就可以處理多種可能的情況,如下:

Console.WriteLine(GetCalendarSeason(new DateTime(2021, 1, 19)));  // output: winter
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 10, 9)));  // output: autumn
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 5, 11)));  // output: spring

static string GetCalendarSeason(DateTime date) => date.Month switch
{
    3 or 4 or 5 => "spring",
    6 or 7 or 8 => "summer",
    9 or 10 or 11 => "autumn",
    12 or 1 or 2 => "winter",
    _ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."),
};
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 1, 19)));  // output: winter
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 10, 9)));  // output: autumn
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 5, 11)));  // output: spring

static string GetCalendarSeason(DateTime date) => date.Month switch
{
    3 or 4 or 5 => "spring",
    6 or 7 or 8 => "summer",
    9 or 10 or 11 => "autumn",
    12 or 1 or 2 => "winter",
    _ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."),
};
$vbLabelText   $csharpLabel

此處,日曆季節是根據所提供的日期所在的月份確定的。

這些模式組合器可以重複使用,以創建更複雜、更精確的匹配條件,從而增強程式碼的靈活性和可讀性。

屬性模式

屬性模式允許將表達式的屬性或欄位與嵌套模式進行配對。 以下程式碼片段展示了一個範例:

static bool IsConferenceDay(DateTime date) => date is { Year: 2020, Month: 5, Day: 19 or 20 or 21 };
static bool IsConferenceDay(DateTime date) => date is { Year: 2020, Month: 5, Day: 19 or 20 or 21 };
$vbLabelText   $csharpLabel

此處的屬性模式可確保提供的日期與指定的會議日期之一相對應。

您也可以將運行時類型檢查和變數聲明整合到屬性模式中,如下所示:

static string TakeFive(object input) => input switch
{
    string { Length: >= 5 } s => s.Substring(0, 5),
    string s => s,
    ICollection<char> { Count: >= 5 } symbols => new string(symbols.Take(5).ToArray()),
    ICollection<char> symbols => new string(symbols.ToArray()),
    null => throw new ArgumentNullException(nameof(input)),
    _ => throw new ArgumentException("Unsupported input type."),
};
static string TakeFive(object input) => input switch
{
    string { Length: >= 5 } s => s.Substring(0, 5),
    string s => s,
    ICollection<char> { Count: >= 5 } symbols => new string(symbols.Take(5).ToArray()),
    ICollection<char> symbols => new string(symbols.ToArray()),
    null => throw new ArgumentNullException(nameof(input)),
    _ => throw new ArgumentException("Unsupported input type."),
};
$vbLabelText   $csharpLabel

這裡使用屬性模式來處理字串和字元集合,確保根據它們的屬性進行正確處理。

位置模式

在 C# 中,位置模式允許解構表達式結果,並將結果值與對應的嵌套模式進行配對。 例如:

public readonly struct Point
{
    public int X { get; }
    public int Y { get; }
    public Point(int x, int y) => (X, Y) = (x, y);
    public void Deconstruct(out int x, out int y) => (x, y) = (X, Y);
}

static string Classify(Point point) => point switch
{
    (0, 0) => "Origin",
    (1, 0) => "Positive X basis end",
    (0, 1) => "Positive Y basis end",
    _ => "Just a point",
};
public readonly struct Point
{
    public int X { get; }
    public int Y { get; }
    public Point(int x, int y) => (X, Y) = (x, y);
    public void Deconstruct(out int x, out int y) => (x, y) = (X, Y);
}

static string Classify(Point point) => point switch
{
    (0, 0) => "Origin",
    (1, 0) => "Positive X basis end",
    (0, 1) => "Positive Y basis end",
    _ => "Just a point",
};
$vbLabelText   $csharpLabel

在這個例子中,位置模式被用來根據點的座標對點進行分類。

此外,您還可以在屬性模式中引用嵌套的屬性或字段,這稱為擴展屬性模式,該模式是在 C# 10 中引入的:

static bool IsAnyEndOnXAxis(Segment segment) =>
    segment is { Start.Y: 0 } or { End.Y: 0 };
static bool IsAnyEndOnXAxis(Segment segment) =>
    segment is { Start.Y: 0 } or { End.Y: 0 };
$vbLabelText   $csharpLabel

此功能允許直接存取嵌套屬性,從而增強屬性模式的靈活性。

這些模式為處理複雜的資料結構提供了強大的機制,並提高了程式碼的可讀性和表達能力。

規律在哪裡?

Var Pattern 允許您匹配任何類型的數據。 這對於在布林表達式中捕獲中間結果或在 switch case 守衛中需要進行多次檢查時特別有用。

以下範例示範如何在布林運算式中使用 var 模式:

static bool IsAcceptable(int id, int absLimit) =>
    SimulateDataFetch(id) is var results 
    && results.Min() >= -absLimit 
    && results.Max() <= absLimit;

static int [] SimulateDataFetch(int id)
{
    var rand = new Random();
    return Enumerable
               .Range(start: 0, count: 5)
               .Select(s => rand.Next(minValue: -10, maxValue: 11))
               .ToArray();
}
static bool IsAcceptable(int id, int absLimit) =>
    SimulateDataFetch(id) is var results 
    && results.Min() >= -absLimit 
    && results.Max() <= absLimit;

static int [] SimulateDataFetch(int id)
{
    var rand = new Random();
    return Enumerable
               .Range(start: 0, count: 5)
               .Select(s => rand.Next(minValue: -10, maxValue: 11))
               .ToArray();
}
$vbLabelText   $csharpLabel

在這個範例中, SimulateDataFetch傳回一個整數數組,而is var模式將結果捕獲到results變數中,從而可以根據其屬性進行後續計算。

此外,var 模式也可用於 switch 表達式或語句中,以編寫更簡潔、更易讀的程式碼。 以下是在 switch case 語句保護中使用 var 模式的範例:

public record Point(int X, int Y);

static Point Transform(Point point) => point switch
{
    var (x, y) when x < y => new Point(-x, y),
    var (x, y) when x > y => new Point(x, -y),
    var (x, y) => new Point(x, y),
};

static void TestTransform()
{
    Console.WriteLine(Transform(new Point(1, 2)));  // output: Point { X = -1, Y = 2 }
    Console.WriteLine(Transform(new Point(5, 2)));  // output: Point { X = 5, Y = -2 }
}
public record Point(int X, int Y);

static Point Transform(Point point) => point switch
{
    var (x, y) when x < y => new Point(-x, y),
    var (x, y) when x > y => new Point(x, -y),
    var (x, y) => new Point(x, y),
};

static void TestTransform()
{
    Console.WriteLine(Transform(new Point(1, 2)));  // output: Point { X = -1, Y = 2 }
    Console.WriteLine(Transform(new Point(5, 2)));  // output: Point { X = 5, Y = -2 }
}
$vbLabelText   $csharpLabel

在這個例子中,var pattern (x, y)捕獲點的座標,允許根據其值進行不同的變換。

在 var 模式中,宣告變數的類型是從與該模式相符的表達式的編譯時類型推斷出來的。

var 模式提供了一種便捷的方式來處理各種事先不知道特定表達式類型的場景,從而提高了程式碼的清晰度和靈活性。

IronPDF庫簡介

IronPDF Document Rendering是 Iron Software 出品的一個專門用來產生 PDF 文件的函式庫。 首先,需要從 NuGet 套件管理器或 Visual Studio 套件管理器安裝程式庫。

# To install from the NuGet Package Manager Console
Install-Package IronPdf
# To install from the NuGet Package Manager Console
Install-Package IronPdf
SHELL

下圖展示如何根據Visual Studio 安裝指南進行安裝。

C# 模式匹配表達式(開發者使用方法):圖 1 - 使用 NuGet 套件管理器安裝 IronPDF

下面的程式碼將示範如何產生一個簡單的PDF文件:

using IronPdf;

namespace IronPatterns
{
    class Program
    {
        static void Main()
        {
            Console.WriteLine("-----------Iron Software-------------");
            var renderer = new ChromePdfRenderer(); // var pattern
            var content = " <h1> Iron Software is Awesome </h1> Made with IronPDF!";

            // Declaration Pattern
            int? nullableX = 8;
            int y = 45;
            object boxedy = y;
            content += "<p>Declaration Pattern</p>";
            if (nullableX is int a && boxedy is int b)
            {
                Console.WriteLine(a + b); // output: 53
                content += $"<p>Output: {(a + b)}</p>";
            }

            // Relational patterns
            content += "<p>Relational patterns</p>";
            var season1 = GetCalendarSeason(new DateTime(2024, 2, 25));
            Console.WriteLine(season1);
            content += $"<p>2024, 2, 25: {season1}</p>";
            var season2 = GetCalendarSeason(new DateTime(2024, 5, 25));
            Console.WriteLine(season2);
            content += $"<p>2024, 5, 25: {season2}</p>";
            var season3 = GetCalendarSeason(new DateTime(2024, 7, 25));
            Console.WriteLine(season3);
            content += $"<p>2024, 7, 25: {season3}</p>";

            var pdf = renderer.RenderHtmlAsPdf(content);
            pdf.SaveAs("output.pdf"); // Saves our PdfDocument object as a PDF        
        }

        static string GetCalendarSeason(DateTime date) => date.Month switch
        {
            >= 3 and < 6 => "spring",
            >= 6 and < 9 => "summer",
            >= 9 and < 12 => "autumn",
            12 or (>= 1 and < 3) => "winter",
            _ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."),
        };
    }
}
using IronPdf;

namespace IronPatterns
{
    class Program
    {
        static void Main()
        {
            Console.WriteLine("-----------Iron Software-------------");
            var renderer = new ChromePdfRenderer(); // var pattern
            var content = " <h1> Iron Software is Awesome </h1> Made with IronPDF!";

            // Declaration Pattern
            int? nullableX = 8;
            int y = 45;
            object boxedy = y;
            content += "<p>Declaration Pattern</p>";
            if (nullableX is int a && boxedy is int b)
            {
                Console.WriteLine(a + b); // output: 53
                content += $"<p>Output: {(a + b)}</p>";
            }

            // Relational patterns
            content += "<p>Relational patterns</p>";
            var season1 = GetCalendarSeason(new DateTime(2024, 2, 25));
            Console.WriteLine(season1);
            content += $"<p>2024, 2, 25: {season1}</p>";
            var season2 = GetCalendarSeason(new DateTime(2024, 5, 25));
            Console.WriteLine(season2);
            content += $"<p>2024, 5, 25: {season2}</p>";
            var season3 = GetCalendarSeason(new DateTime(2024, 7, 25));
            Console.WriteLine(season3);
            content += $"<p>2024, 7, 25: {season3}</p>";

            var pdf = renderer.RenderHtmlAsPdf(content);
            pdf.SaveAs("output.pdf"); // Saves our PdfDocument object as a PDF        
        }

        static string GetCalendarSeason(DateTime date) => date.Month switch
        {
            >= 3 and < 6 => "spring",
            >= 6 and < 9 => "summer",
            >= 9 and < 12 => "autumn",
            12 or (>= 1 and < 3) => "winter",
            _ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."),
        };
    }
}
$vbLabelText   $csharpLabel

輸出

C# 模式匹配表達式(開發者如何理解):圖 2

代碼詳情

這裡我們使用IronPDF 的ChromePdfRenderer類別將 HTML 字串儲存到 PDF 文件中。 輸出結果儲存到"output.pdf"文件中。

試試許可證

IronPDF 可以使用從IronPDF 許可頁面獲得的試用許可證。 請提供您的電子郵件地址,以便產生許可證密鑰並發送到您的郵箱。

"IronPDF.LicenseKey": "<Your Key>"
"IronPDF.LicenseKey": "<Your Key>"
$vbLabelText   $csharpLabel

將許可證金鑰放入appsettings.json檔案中,如上所示。

結論

C# 中的模式匹配表達式提供了一種強大且靈活的方式,可以以簡潔易讀的方式編寫條件語句、類型檢查和物件解構。 透過利用模式匹配,開發人員可以提高程式碼的清晰度和可維護性,同時減少樣板程式碼和冗餘程式碼。 無論是型別檢查、switch 語句或解構,模式比對表達式都提供了一套多功能的工具集,用於處理 C# 中的各種程式設計任務。

總之,掌握模式匹配表達式可以大大提高你的 C# 程式設計技能,使你能夠編寫更簡潔、更具表現力、更易於理解和維護的程式碼。 我們也介紹了IronPDF 的 HTML 轉 PDF 產生功能,可用於產生 PDF 文件。

常見問題解答

如何在C#中使用模式匹配來提高程式碼可讀性?

C# 中的模式匹配功能可讓開發人員編寫更簡潔、更具表現力的程式碼,讓條件語句更清晰易懂。這透過降低程式碼區塊的複雜性來提高程式碼的可讀性和可維護性。

C# 中有哪些不同類型的模式比對表達式?

C# 支援多種模式比對表達式,包括is表達式、 switch語句和switch表達式。每種類型都提供了不同的表達式求值方式,並根據匹配的模式執行程式碼。

如何使用C#產生PDF文件?

您可以使用 Iron Software 出品的 IronPDF 庫,在 C# 中產生 PDF 文件。它允許將 HTML 內容轉換為 PDF,並且可以透過 NuGet 輕鬆安裝,提供豐富的 PDF 生成功能。

C#模式符合中的宣告模式和型別模式是什麼?

C# 中的宣告和類型模式會檢查表達式的執行時間類型是否與指定的類型匹配,並在匹配成功時允許宣告新的局部變量,從而實現類型安全的操作。

C# 中常數模式是如何運作的?

C# 中的常數模式用於檢查表達式是否等於特定的常數值(例如整數或字串),如果找到匹配項,則執行某些邏輯,從而實現直接的常數值比較。

C#中關係模式的用途是什麼?

C# 中的關係模式允許使用關係運算子(例如<><=>=將表達式與常數進行比較。這對於在程式碼中實現簡潔的範圍檢查非常有用。

如何在 C# 中應用邏輯模式?

C# 中的邏輯模式使用邏輯運算子(例如andornot )組合其他模式,從而實現複雜的模式匹配條件,可以同時評估多個標準。

C# 中的 discard 模式是什麼?它何時使用?

C# 中的丟棄模式以_表示,它符合任何表達式,包括null ,通常用於需要忽略特定值的情況,例如switch表達式。

如何在 C# 中使用屬性模式?

C# 中的屬性模式允許開發人員將物件的屬性或欄位與嵌套模式進行匹配,從而提供了一種在保持程式碼清晰簡潔的同時對物件結構進行深入檢查的方法。

Jacob Mellor,Team Iron 首席技術官
首席技術長

Jacob Mellor 是 Iron Software 的首席技術官,也是一位富有遠見的工程師,率先開發了 C# PDF 技術。作為 Iron Software 核心程式碼庫的最初開發者,他自公司成立之初便參與塑造了其產品架構,並與執行長 Cameron Rimington 一起將其發展成為一家擁有 50 多名員工、服務於 NASA、特斯拉和全球政府機構的公司。

Jacob 於 1998 年至 2001 年在曼徹斯特大學獲得土木工程一級榮譽學士學位。 1999 年,他在倫敦創辦了自己的第一家軟體公司;2005 年,他創建了自己的第一個 .NET 元件。此後,他專注於解決微軟生態系統中的複雜問題。

他的旗艦產品 IronPDF 和 IronSuite .NET 庫在全球 NuGet 上的安裝量已超過 3000 萬次,其基礎程式碼持續為全球開發者工具提供支援。憑藉 25 年的商業經驗和 41 年的程式設計專長,Jacob 始終致力於推動企業級 C#、Java 和 Python PDF 技術的創新,同時指導下一代技術領導者。