C# Discriminated Unions (How it Works for Developers)
作為一名使用IronPDF進行動態PDF生成的.NET開發者,您通常需要表示和管理一系列特定型別的資料——如不同型別的文件資料、日誌記錄資訊、使用者角色或導出選項。 這就是C#判別聯合概念派上用場的地方。
雖然C#不像F#或Rust那樣原生支援判別聯合,但您仍然可以有效模擬判別聯合。 在這篇部落格文章中,我們將深入探討如何在C#中定義和使用判別聯合型別,展示如何將其應用於IronPDF以進行實際的PDF處理,並探索當與模式匹配配對時,這種模式能提供的優勢。
What Are Discriminated Unions in C#?
判別聯合,也被稱為標記聯合或聯合型別,允許變數持有一個來自有限選項集的值,每個選項都與一個獨特的案例識別符相關聯。
在其他語言如F#中,您可以使用union關鍵字來定義它們。 C#沒有原生提供這個功能,但開發者可以通過巧妙結合記錄型別、類和switch表達式來模擬它們。
例如:
public abstract record PdfAction;
public record GenerateReport(string ReportName) : PdfAction;
public record LogError(string Message) : PdfAction;
public record ExportToExcel(string FilePath) : PdfAction;
public abstract record PdfAction;
public record GenerateReport(string ReportName) : PdfAction;
public record LogError(string Message) : PdfAction;
public record ExportToExcel(string FilePath) : PdfAction;
Public MustOverride ReadOnly Property PdfAction() As record
public record GenerateReport(String ReportName) : PdfAction
public record LogError(String Message) : PdfAction
public record ExportToExcel(String FilePath) : PdfAction
上述的每個記錄都代表該聯合的唯一個案。 基礎PdfAction型別是判別體。
為什麼判別聯合在IronPDF工作流程中很重要
想像一下您正在使用IronPDF構建PDF報告生成器,您需要根據使用者的輸入執行不同的操作——可能是生成PDF、記錄錯誤或導出資料。
在C#中使用判別聯合可以讓您清楚地表示這些選項型別,從而達到編譯時安全、減少錯誤和更清晰的邏輯。
這是您可能在IronPDF中使用的方法:
void HandlePdfAction(PdfAction action)
{
switch (action)
{
case GenerateReport r:
var pdf = new IronPdf.HtmlToPdf().RenderHtmlAsPdf("<h1>" + r.ReportName + "</h1>");
pdf.SaveAs(r.ReportName + ".pdf");
break;
case LogError e:
Console.WriteLine("Logging Error: " + e.Message);
break;
case ExportToExcel x:
Console.WriteLine("Exporting to Excel at " + x.FilePath);
break;
default:
throw new NotSupportedException("Unknown action");
}
}
void HandlePdfAction(PdfAction action)
{
switch (action)
{
case GenerateReport r:
var pdf = new IronPdf.HtmlToPdf().RenderHtmlAsPdf("<h1>" + r.ReportName + "</h1>");
pdf.SaveAs(r.ReportName + ".pdf");
break;
case LogError e:
Console.WriteLine("Logging Error: " + e.Message);
break;
case ExportToExcel x:
Console.WriteLine("Exporting to Excel at " + x.FilePath);
break;
default:
throw new NotSupportedException("Unknown action");
}
}
Private Sub HandlePdfAction(ByVal action As PdfAction)
Select Case action
'INSTANT VB TODO TASK: The following 'case' pattern variable is not converted by Instant VB:
'ORIGINAL LINE: case GenerateReport r:
Case GenerateReport r
Dim pdf = (New IronPdf.HtmlToPdf()).RenderHtmlAsPdf("<h1>" & r.ReportName & "</h1>")
pdf.SaveAs(r.ReportName & ".pdf")
'INSTANT VB TODO TASK: The following 'case' pattern variable is not converted by Instant VB:
'ORIGINAL LINE: case LogError e:
Case LogError e
Console.WriteLine("Logging Error: " & e.Message)
'INSTANT VB TODO TASK: The following 'case' pattern variable is not converted by Instant VB:
'ORIGINAL LINE: case ExportToExcel x:
Case ExportToExcel x
Console.WriteLine("Exporting to Excel at " & x.FilePath)
Case Else
Throw New NotSupportedException("Unknown action")
End Select
End Sub
這種方法保持您的程式碼組織良好且強大,並且使開發者更容易在單一位置理解所有可能的選項。
Simulating Discriminated Unions in C# – Struct vs. Record vs. Class
雖然C#缺乏union關鍵字,但您可以使用以下方法來模擬判別聯合:
- 記錄:理想用於不可變資料,並支持清晰的模式匹配。
- 類:在繼承和引用語義上更靈活。
- 結構:對於值型別有用,但在處理引用型別或繼承時靈活性較低。

如果性能和記憶體佈局很重要——例如在高吞吐量的PDF日誌記錄中,您可能會考慮謹慎使用結構型判別聯合:
public interface IAction { }
public readonly struct SaveAction : IAction
{
public string FileName { get; }
public SaveAction(string fileName) => FileName = fileName;
}
public interface IAction { }
public readonly struct SaveAction : IAction
{
public string FileName { get; }
public SaveAction(string fileName) => FileName = fileName;
}
Public Interface IAction
End Interface
'INSTANT VB WARNING: VB has no equivalent to the C# readonly struct:
'ORIGINAL LINE: public readonly struct SaveAction : IAction
Public Structure SaveAction
Implements IAction
Public ReadOnly Property FileName() As String
Public Sub New(ByVal fileName As String)
Me.FileName = fileName
End Sub
End Structure
注意:使用結構時,尤其是在依賴switch表達式時,您將失去一些模式匹配的好處。
Benefits of Using Discriminated Unions in C
採用這種軟體工程模式有幾個關鍵優勢:
- 編譯時安全:您將在運行時之前發現switch表達式中缺失的案例。
- 更清晰的邏輯:用命名的案例來編寫、評論和推理行為更容易。
- 關注點分離:您基於<大硬刷>資料</大硬刷>而不是型別層次結構來分離行為。
- 重構的方便性:新增或刪除案例變得更為簡單。
當與IronPDF配合使用時,這使得管理使用者輸入、渲染邏輯或建立具有不同值管線的動態範本更容易。
何時與IronPDF一起使用判別聯合
以下是該模式表現優秀的一些實際情境:
- PDF生成工作流程:文件生命周期中的不同步驟(生成、儲存、郵件)。
- 權限模型:代表不同的使用者存取級別。
- 日誌系統:使用判別聯合型別對日誌級別(資訊、錯誤、除錯)。
- 單元測試:將測試行動定義為聯合型別以保持邏輯樹的可維護性。
- 導出選項:代表輸出目標,例如PDF、Excel、Word 作為聯合實例。

範例 - 處理來自UI事件的PDF動作
假如您正在捕捉UI事件並希望使用判別聯合將它們路由到IronPDF任務:
public abstract record UserAction;
public record GeneratePdf(string HtmlContent, string FileName) : UserAction;
public record ShowMessage(string Text) : UserAction;
public record ExitApplication() : UserAction;
void OnUserEvent(UserAction action)
{
switch (action)
{
case GeneratePdf pdf:
var renderer = new IronPdf.HtmlToPdf();
var document = renderer.RenderHtmlAsPdf(pdf.HtmlContent);
document.SaveAs(pdf.FileName);
break;
case ShowMessage msg:
MessageBox.Show(msg.Text);
break;
case ExitApplication:
Application.Exit();
break;
}
}
public abstract record UserAction;
public record GeneratePdf(string HtmlContent, string FileName) : UserAction;
public record ShowMessage(string Text) : UserAction;
public record ExitApplication() : UserAction;
void OnUserEvent(UserAction action)
{
switch (action)
{
case GeneratePdf pdf:
var renderer = new IronPdf.HtmlToPdf();
var document = renderer.RenderHtmlAsPdf(pdf.HtmlContent);
document.SaveAs(pdf.FileName);
break;
case ShowMessage msg:
MessageBox.Show(msg.Text);
break;
case ExitApplication:
Application.Exit();
break;
}
}
Public MustOverride ReadOnly Property UserAction() As record
public record GeneratePdf(String HtmlContent, String FileName) : UserAction
public record ShowMessage(String Text) : UserAction
public record ExitApplication() : UserAction
'INSTANT VB TODO TASK: Local functions are not converted by Instant VB:
'void OnUserEvent(UserAction action)
'{
' switch (action)
' {
' case GeneratePdf pdf:
' var renderer = New IronPdf.HtmlToPdf();
' var document = renderer.RenderHtmlAsPdf(pdf.HtmlContent);
' document.SaveAs(pdf.FileName);
' break;
' case ShowMessage msg:
' MessageBox.Show(msg.Text);
' break;
' case ExitApplication:
' Application.@Exit();
' break;
' }
'}
這讓您可以用清晰的邏輯來表示事件,並減少對公用物件型別或過於動態的處理的依賴。
Future Outlook – Will C# Ever Support Native Discriminated Unions?
已經有提案要在C#中增加對判別聯合的原生支援,尤其是在對更表達型型別系統的需求增長的情況下。 雖然該語言尚未引入真正的union關鍵字,但C#仍在不斷演變——引入類似於記錄型別、模式匹配和switch表達式等特性,這些特性與完整的判別聯合功能越來越接近。
對現代、支援功能型語言特性的.NET開發者來說,這一領域值得密切關注。
總結
即使沒有原生支援,在C#中使用判別聯合也可以顯著改善您在IronPDF應用中如何結構和表示邏輯。 通過利用記錄型別、switch表達式和基礎型別,您將使您的程式碼庫更易讀、更易維護、抗錯誤——同時也開啟了一個以更聲明式和表達性方式處理PDF相關任務的門路。
如果您是一位構建現代、靈活.NET應用的軟體工程師,這種模式是您工具包中必備的一員。
立即免費試用IronPDF
準備好將您的C# PDF生成提升到下一個層次了嗎? 下載IronPDF並開始免費試用。 無論您是從HTML生成文件、記錄導出,還是使用判別聯合自動化報告——IronPDF為您的應用程式提供了應有的性能和效能。
常見問題
我如何在C#中實現區分聯合?
在C#中,您可以通過定義基類和多個派生類來表示每個可能的情況來模擬區分聯合。這種方法結合模式匹配後,允許您有效地管理多個相關的資料型別。
模式匹配在區分聯合中起什麼作用?
在C#中,模式匹配在處理區分聯合時至關重要,因為它讓您可以以簡潔的方式處理聯合的每個情況,提高程式碼的可讀性,並減少多個條件語句的需求。
區分聯合與C#中的枚舉如何比較?
雖然區分聯合和枚舉都允許您定義固定的選項集,但區分聯合提供了更多的靈活性,因為它們可以容納不同型別的資料,而枚舉僅限於單一資料型別的命名常數。
使用區分聯合時,我可以用Iron Software增強資料操作嗎?
是的,像IronPDF這樣的Iron Software產品可以通過提供高級資料處理和操作功能來補充區分聯合,這使得在.NET應用程式中更輕鬆地操作和呈現不同型別的資料。
在C#中使用區分聯合有什麼優勢?
區分聯合通過允許您定義具有特定可能形式的型別來增強C#程式碼中的型別安全性、清晰性和可維護性,這促進了強健的型別檢查並減少錯誤。
使用區分聯合如何影響程式碼的可讀性?
通過允許開發者清楚地定義和處理多個相關資料型別,區分聯合提高了程式碼的可讀性。模式匹配通過減少對複雜條件邏輯的需求進一步簡化了程式碼。
在C#中使用類來模擬區分聯合有何意義?
在C#中使用類來模擬區分聯合涉及建立一個基類,對每種情況建立衍生類,這提供了類似於函式式編程語言的靈活和表達方式來建模不同的相關型別。
區分聯合如何增強C#中的錯誤處理?
區分聯合可以通過提供更精確的型別檢查和啟用模式匹配來改善錯誤處理,這有助於在編譯時捕獲潛在錯誤,提高您的應用程式的可靠性。




