在實際環境中測試
在生產環境中測試無浮水印。
在任何需要的地方都能運作。
在 C# 中,模式匹配是一個強大的功能,它在 C# 7.0 中被引入,並且在後續版本中得到擴展。它允許開發者在處理條件語句、類型檢查和對象解構時,寫出更簡潔和有表達力的代碼。
模式匹配表達式提供了一種靈活而直觀的方式來將值與模式匹配並執行對應的代碼塊。在本文中,我們將探討 C# 中模式匹配表達式的複雜性,包括語法、用例和代碼示例。本文結尾,我們還會探討一些其他內容。 IronPDF 從 Iron Software 在C#應用程式中即時生成PDF文件。
C# 代碼中的模式匹配帶來了許多優點:
模式匹配支援以下表達式:
可以用來匹配構造的模式如下:
宣告和類型模式是 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!
}
Dim greeting As Object = "Iron Software is Awesome!"
Dim tempVar As Boolean = TypeOf greeting Is String
Dim message As String = If(tempVar, DirectCast(greeting, String), Nothing)
If tempVar Then
Console.WriteLine(message.ToLower()) ' output: Iron Software is Awesome!
End If
在這裡,宣告模式確保如果表達式 greeting 匹配類型 string,它將被賦值給變量 message,使後續操作成為可能。
當以下任何條件成立時,宣告模式成立:
考慮以下示例來演示上述條件:
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
}
Dim nullableX? As Integer = 8
Dim y As Integer = 45
Dim boxedy As Object = y
Dim tempVar As Boolean = TypeOf boxedy Is Integer
Dim b As Integer = If(tempVar, DirectCast(boxedy, Integer), Nothing)
Dim tempVar2 As Boolean = TypeOf nullableX Is Integer
Dim a As Integer = If(tempVar2, CInt(nullableX), Nothing)
If tempVar2 AndAlso tempVar Then
Console.WriteLine(a + b) ' output: 53
End If
在這裡,nullableX
匹配模式,因為它是一個可空值類型,底層類型是 int,而 boxedy
匹配是因為它可以被拆箱為 int。
當您只需要檢查表達式的類型而不需要聲明新變量時,您可以利用丟棄符 _,如下例所示:
public static decimal CalculateToll(this 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(this 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)),
};
'INSTANT VB TODO TASK: The following 'switch expression' was not converted by Instant VB:
'public static decimal CalculateToll(this 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)),
'};
在此程式碼片段中,_ 作為匹配任何類型的 Vehicle 佔位符。
聲明模式和類型模式確保表達式在模式匹配之前是非空的。您可以使用否定的 null 常量模式來檢查非空,如下面所示:
if (inputVal is not null)
{
// ...
}
if (inputVal is not null)
{
// ...
}
If inputVal IsNot Nothing Then
' ...
End If
此否定確保在進行進一步操作之前輸入不為空。
通過在 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)),
};
Dim tempVar As Decimal
Select Case visitorCount
Case 1
tempVar = 2.0D
Case 2
tempVar = 10.0D
Case 3
tempVar = 25.0D
Case 4
tempVar = 60.0D
Case 0
tempVar = 0.0D
Case Else
'INSTANT VB TODO TASK: Throw expressions are not converted by Instant VB:
'ORIGINAL LINE: tempVar = throw new ArgumentException(string.Format("Not supported number of visitors: {0}", visitorCount), nameof(visitorCount));
tempVar = throw New ArgumentException($"Not supported number of visitors: {visitorCount}", NameOf(visitorCount))
End Select
'INSTANT VB TODO TASK: Local functions are not converted by Instant VB:
'public static decimal GetGroupTicketPrice(int visitorCount)
'{
' Return tempVar;
'}
在這裡,常數模式會檢查 visitorCount
是否匹配指定的常數值並返回相應的票價。
在常數模式中,您可以使用各種類型的常數表達式,例如:
整數或浮點數字面量。
字符。
字串字面量。
布爾值。 (真或假)。
枚舉值。
所宣告的常數欄位或區域變數的名稱。
型別為 Span 的表達式
若要檢查空值,請使用如下常量模式:
if (inputVal is null)
{
return;
}
if (inputVal is null)
{
return;
}
If inputVal Is Nothing Then
Return
End If
在這裡,該模式確保在進行進一步操作之前輸入為 null。
您也可以使用否定的 null 常量模式來確認非 null 值:
if (inputVal is not null)
{
// ...
}
if (inputVal is not null)
{
// ...
}
If inputVal IsNot Nothing Then
' ...
End If
此模式驗證輸入不是空值,允許隨後的操作可以安全地執行。
通過將常量模式整合進 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",
};
Console.WriteLine(Classify(20)) ' output: Too high
Console.WriteLine(Classify(Double.NaN)) ' output: Unknown
Console.WriteLine(Classify(4)) ' output: Acceptable
'INSTANT VB TODO TASK: The following 'switch expression' was not converted by Instant VB:
'static string Classify(double measurement) => measurement switch
'{
' < -4.0 => "Too low",
' > 10.0 => "Too high",
' double.NaN => "Unknown",
' _ => "Acceptable",
'};
這裡,關係模式根據特定閾值來比較測量,以確定其分類。
關係模式的右側必須是一個常量表達式,可以是整數、浮點數、字符或 enum
類型。可以在左側使用 <
、>
、<=
或 >=
操作符。
要將表達式結果匹配到某個範圍內,請使用如下所示的合取和模式:
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}."),
};
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
'INSTANT VB TODO TASK: The following 'switch expression' was not converted by Instant VB:
'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}."),
'};
這段摘錄描述了如何利用連接詞「和」模式來確定月份落在特定範圍內的季節。它還提到關係模式提供了一種簡潔且富表現力的方式來將表達式結果與常數進行比較,從而提高代碼的清晰度和可維護性。
捨棄模式,由 _ 表示,用於匹配任何表達式,包括 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,
};
Console.WriteLine(GetDiscountInPercent(DayOfWeek.Friday)) ' output: 5.0
Console.WriteLine(GetDiscountInPercent(Nothing)) ' output: 0.0
Console.WriteLine(GetDiscountInPercent(CType(10, DayOfWeek))) ' output: 0.0
Dim tempVar As Decimal
Select Case dayOfWeek
Case DayOfWeek.Monday
tempVar = 0.5D
Case DayOfWeek.Tuesday
tempVar = 12.5D
Case DayOfWeek.Wednesday
tempVar = 7.5D
Case DayOfWeek.Thursday
tempVar = 12.5D
Case DayOfWeek.Friday
tempVar = 5.0D
Case DayOfWeek.Saturday
tempVar = 2.5D
Case DayOfWeek.Sunday
tempVar = 2.0D
Case Else
tempVar = 0.0D
End Select
'INSTANT VB TODO TASK: Local functions are not converted by Instant VB:
'static decimal GetDiscountInPercent(System.Nullable(Of DayOfWeek) dayOfWeek)
'{
' Return tempVar;
'}
在上述範例中,丟棄模式處理了所有可能的輸入值。所有的星期天數皆被處理並代表了預設值。這樣一來,所有可能的值都得到了處理。丟棄模式不能在is表達式或switch語句中作為模式使用。在這種情況下,你可以使用帶有丟棄的var模式,例如var _,以匹配任何表達式。然而,丟棄模式在switch表達式中是允許的。欲了解更多詳情,請參閱功能提案說明中的丟棄模式部分。
C#中的邏輯模式提供了強大的模式匹配工具,包括否定、連接和分離,這些工具允許更靈活和更具表現力的匹配條件。
否定模式,用「not」表示,當否定的模式不匹配表達式時,才匹配表達式。這在檢查表達式是否非空時特別有用,如下所示:
if (input is not null)
{
// ...
}
if (input is not null)
{
// ...
}
If input IsNot Nothing Then
' ...
End If
這裡,如果輸入不為空,則執行程式碼區塊。
連接模式使用「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",
};
Console.WriteLine(Classify(13)) ' output: High
Console.WriteLine(Classify(-100)) ' output: Too low
Console.WriteLine(Classify(5.7)) ' output: Acceptable
'INSTANT VB TODO TASK: The following 'switch expression' was not converted by Instant VB:
'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",
'};
在此範例中,測量根據其數值範圍進行分類。
不相交模式使用「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}."),
};
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
Dim tempVar As String
Select Case [date].Month
Case 3, 4, 5
tempVar = "spring"
Case 6, 7, 8
tempVar = "summer"
Case 9, 10, 11
tempVar = "autumn"
Case 12, 1, 2
tempVar = "winter"
Case Else
'INSTANT VB TODO TASK: Throw expressions are not converted by Instant VB:
'ORIGINAL LINE: tempVar = throw new ArgumentOutOfRangeException(nameof(date), string.Format("Date with unexpected month: {0}.", date.Month));
tempVar = throw New ArgumentOutOfRangeException(NameOf([date]), $"Date with unexpected month: {[date].Month}.")
End Select
'INSTANT VB TODO TASK: Local functions are not converted by Instant VB:
' static string GetCalendarSeason(DateTime @date)
' {
' Return tempVar;
' }
在這裡,日曆季節是根據提供的日期月份來決定的。
這些模式組合器可以反覆使用,以創建更複雜和精確的匹配條件,從而提高您的代碼的靈活性和可讀性。
屬性模式允許將表達式的屬性或欄位與嵌套模式進行匹配。以下代碼片段展示了一個例子:
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 };
Shared Function IsConferenceDay(ByVal [date] As DateTime) As Boolean
'INSTANT VB TODO TASK: The following 'is' operator pattern is not converted by Instant VB:
Return [date] is { Year: 2020, Month: 5, Day: 19 [or] 20 [or] 21 }
End Function
此處,屬性模式確保提供的日期對應於指定的會議日之一。
您也可以在屬性模式中引入運行時類型檢查和變量聲明,如下所示:
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."),
};
'INSTANT VB TODO TASK: The following 'switch expression' was not converted by Instant VB:
'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."),
'};
在此,屬性模式用於處理字符串和字符集合,確保根據它們的屬性進行適當處理。
在 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",
};
'INSTANT VB WARNING: VB has no equivalent to the C# readonly struct:
'ORIGINAL LINE: public readonly struct Point
Public Structure Point
Public ReadOnly Property X() As Integer
Public ReadOnly Property Y() As Integer
Public Sub New(ByVal x As Integer, ByVal y As Integer)
'INSTANT VB TODO TASK: VB has no equivalent to the C# deconstruction assignments:
(X, Y) = (x, y)
End Sub
Public Sub Deconstruct(<System.Runtime.InteropServices.Out()> ByRef x As Integer, <System.Runtime.InteropServices.Out()> ByRef y As Integer)
'INSTANT VB TODO TASK: VB has no equivalent to the C# deconstruction assignments:
(x, y) = (X, Y)
End Sub
End Structure
'INSTANT VB TODO TASK: The following 'switch expression' was not converted by Instant VB:
'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",
'};
在此範例中,位置模式被用於根據點的座標進行分類。
此外,您可以引用屬性模式內的嵌套屬性或欄位,這稱為擴展屬性模式,是在 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 };
Shared Function IsAnyEndOnXAxis(ByVal segment As Segment) As Boolean
'INSTANT VB TODO TASK: The following 'is' operator pattern is not converted by Instant VB:
Return segment is { Start.Y: 0 } [or] { [End].Y: 0 }
End Function
此功能通過允許對嵌套屬性的直接訪問來增強屬性模式的靈活性。
這些模式提供了強大的機制來處理複雜的數據結構並提高您的代碼的可讀性和表達性。
Var Pattern 允許您匹配任何類型。這在布林表達式中捕獲中間結果或在 switch case 守衛中需要多次檢查時特別有用。
以下是一個在布林表達式中使用 var pattern 的示例:
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();
}
Shared Function IsAcceptable(ByVal id As Integer, ByVal absLimit As Integer) As Boolean
Dim tempVar As Boolean = TypeOf SimulateDataFetch(id) Is var
Dim results = If(tempVar, CType(SimulateDataFetch(id), var), Nothing)
Return tempVar AndAlso results.Min() >= -absLimit AndAlso results.Max() <= absLimit
End Function
Shared Function SimulateDataFetch(ByVal id As Integer) As Integer()
Dim rand = New Random()
Return Enumerable.Range(start:= 0, count:= 5).Select(Function(s) rand.Next(minValue:= -10, maxValue:= 11)).ToArray()
End Function
在此範例中,SimulateDataFetch
返回一個整數陣列,而 is var 模式將結果捕獲在 results 變數中,允許根據其屬性進行後續計算。
此外,var 模式可用於 switch 表達式或語句中,以實現更簡潔和可讀的代碼。以下是一個在 switch 案例防護中使用 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 }
}
'INSTANT VB TODO TASK: C# 'records' are not converted by Instant VB:
'public record Point(int X, int Y)
'INSTANT VB TODO TASK: The following 'switch expression' was not converted by Instant VB:
'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),
'};
Shared Sub 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 }
End Sub
在此範例中,var 模式 (x,y) 捕捉點的坐標,根據其數值允許進行不同的變換。
在 var 模式中,宣告變數的型別是從與模式匹配的運算式的編譯時型別推斷出來的。
var 模式提供了一種方便的方法來處理各種情況,其中特定的運算式型別事先未知,從而提高程式碼的清晰度和靈活性。
IronPDF 是一個來自Iron Software的庫,專門用於PDF文件生成。要開始,首先需要從NuGet包管理器或Visual Studio包管理器安裝該庫。
Install-Package IronPdf
下圖顯示了如何從 Visual Studio.
在下面的程式碼中,我們將看到如何生成一個簡單的PDF文檔:
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>Ouput:{(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:{season1}</p>";
var season3 = GetCalendarSeason(new DateTime(2024, 7, 25));
Console.WriteLine(season3);
content += $"<p>2024, 7, 25:{season1}</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}."),
};
}
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>Ouput:{(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:{season1}</p>";
var season3 = GetCalendarSeason(new DateTime(2024, 7, 25));
Console.WriteLine(season3);
content += $"<p>2024, 7, 25:{season1}</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}."),
};
}
Namespace IronPatterns
Friend Class Program
Shared Sub Main()
Console.WriteLine("-----------Iron Software-------------")
Dim renderer = New ChromePdfRenderer() ' var pattern
Dim content = " <h1> Iron Software is Awesome </h1> Made with IronPDF!"
' Declaration Pattern
Dim nullableX? As Integer = 8
Dim y As Integer = 45
Dim boxedy As Object = y
content &= "<p>Declaration Pattern</p>"
Dim tempVar As Boolean = TypeOf boxedy Is Integer
Dim b As Integer = If(tempVar, DirectCast(boxedy, Integer), Nothing)
Dim tempVar2 As Boolean = TypeOf nullableX Is Integer
Dim a As Integer = If(tempVar2, CInt(nullableX), Nothing)
If tempVar2 AndAlso tempVar Then
Console.WriteLine(a + b) ' output: 53
content &= $"<p>Ouput:{(a + b)}</p>"
End If
'Relational patterns
content &= "<p>Relational patterns</p>"
Dim season1 = GetCalendarSeason(New DateTime(2024, 2, 25))
Console.WriteLine(season1)
content &= $"<p>2024, 2, 25:{season1}</p>"
Dim season2 = GetCalendarSeason(New DateTime(2024, 5, 25))
Console.WriteLine(season2)
content &= $"<p>2024, 5, 25:{season1}</p>"
Dim season3 = GetCalendarSeason(New DateTime(2024, 7, 25))
Console.WriteLine(season3)
content &= $"<p>2024, 7, 25:{season1}</p>"
Dim pdf = renderer.RenderHtmlAsPdf(content)
pdf.SaveAs("output.pdf") ' Saves our PdfDocument object as a PDF
End Sub
'INSTANT VB TODO TASK: The following 'switch expression' was not converted by Instant VB:
' 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}."),
' };
End Class
End Namespace
在這裡我們使用 IronPDF ChromePdfRenderer
將 HTML 字串儲存為 PDF 文件。輸出被儲存到 "output.pdf" 文件。
IronPDF 可以使用從 這裡. 提供電子郵件地址以生成將發送到您電子郵件中的授權金鑰。
"IronPDF.LicenseKey": "<Your Key>"
"IronPDF.LicenseKey": "<Your Key>"
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'"IronPDF.LicenseKey": "<Your Key>"
將授權金鑰放置在 AppSettings.Json 文件中,如上所示。
C#中的模式匹配表達式提供了一種強大且靈活的方式,以簡潔且可讀的方式編寫條件語句、類型檢查和對象解構。通過利用模式匹配,開發人員可以提高代碼的清晰度和可維護性,同時減少樣板代碼和冗餘。無論是類型檢查、switch語句還是解構,模式匹配表達式都提供了一個多功能工具集合,用於應對C#中的各種編程任務。
總之,掌握模式匹配表達式可以大大提高您的C#編程技能,使您能夠編寫更乾淨、更具表達力的代碼,這些代碼更易於理解和維護。在本文中,我們還討論了 IronPDF 可用於生成 PDF 文件。