.NET 幫助

C# 判別聯合(它如何為開發者工作)

Kannaopat Udonpant
坎納帕特·烏頓潘
2024年10月23日
分享:

區別聯合,也稱為標記聯合或和類型,是一種強大的工具,用於建模可以採取不同形式的數據,但這些形式具有明確且有限的可能情況。 雖然 C# 沒有像一些其他語言那樣的原生判別聯合類型(例如 F# 或 Rust),您可以使用多種技術來模擬區分聯合。 在本教程中,我們將深入探討區分聯合,如何在 C# 中實現它們,以及它們的實際使用案例。IronPDF 庫.

什麼是區分聯合?

簡單來說,判別聯合是一種可以持有多個預定義的形式或值中的一種類型。 它提供了一種建立類型安全結構的方法,封裝不同的類型或值,同時在編譯時確保只處理有效的情況。

想像一個情境,你想表達一個操作的結果。 該操作可能成功,返回一些數據,或失敗,返回錯誤訊息。 判別聯合將允許您在單一類型中表示這兩種可能的結果。

範例:在C#中模擬區分聯合

下面是一個如何在 C# 中使用類結構模擬區分聯合的例子:

public abstract class OperationResult<T>
{
    private OperationResult() { }
    public sealed class Success : OperationResult<T>
    {
        public T Value { get; }
        public Success(T value) => Value = value;
        public override string ToString() => $"Success: {Value}";
    }
    public sealed class Failure : OperationResult<T>
    {
        public string Error { get; }
        public Failure(string error) => Error = error;
        public override string ToString() => $"Failure: {Error}";
    }
    public static OperationResult<T> CreateSuccess(T value) => new Success(value);
    public static OperationResult<T> CreateFailure(string error) => new Failure(error);
}
public abstract class OperationResult<T>
{
    private OperationResult() { }
    public sealed class Success : OperationResult<T>
    {
        public T Value { get; }
        public Success(T value) => Value = value;
        public override string ToString() => $"Success: {Value}";
    }
    public sealed class Failure : OperationResult<T>
    {
        public string Error { get; }
        public Failure(string error) => Error = error;
        public override string ToString() => $"Failure: {Error}";
    }
    public static OperationResult<T> CreateSuccess(T value) => new Success(value);
    public static OperationResult<T> CreateFailure(string error) => new Failure(error);
}

在此範例中,OperationResult是一個抽象類,代表我們的判別聯合類型。 它可以是類型為 T 的成功,或是帶有錯誤信息的失敗。 私有的構造函數確保這類類別的實例只能通過預定義的案例來創建。

使用模式匹配與辨別聯合體

C# 提供強大的模式匹配功能,非常適合與區分聯合一起使用。 讓我們擴展我們的 OperationResult使用 switch 表達式處理不同案例的方法範例。

public string HandleResult(OperationResult<int> result) =>
    result switch
    {
        OperationResult<int>.Success success => $"Operation succeeded with value: {success.Value}",
        OperationResult<int>.Failure failure => $"Operation failed with error: {failure.Error}",
        _ => throw new InvalidOperationException("Unexpected result type")
    };
public string HandleResult(OperationResult<int> result) =>
    result switch
    {
        OperationResult<int>.Success success => $"Operation succeeded with value: {success.Value}",
        OperationResult<int>.Failure failure => $"Operation failed with error: {failure.Error}",
        _ => throw new InvalidOperationException("Unexpected result type")
    };

此處的 switch 表達式處理 OperationResult 的成功和失敗情況。. 這確保了在編譯時涵蓋所有可能的情況,提供類型安全並降低運行時錯誤的風險。

區分聯合的擴展方法

您可以使用擴展方法來擴展區分聯合的功能。 例如,讓我們為我們的 OperationResult 創建一個擴展方法。以判斷結果是否成功:

public static class OperationResultExtensions
{
    public static bool IsSuccess<T>(this OperationResult<T> result) =>
        result is OperationResult<T>.Success;
}
public static class OperationResultExtensions
{
    public static bool IsSuccess<T>(this OperationResult<T> result) =>
        result is OperationResult<T>.Success;
}

此公有靜態布林方法檢查結果是否為 Success 情況的實例。

在 C# 中對區分聯合的原生支持

C#不像某些其他語言那樣對判別聯合有原生的支持,但社群中正在進行關於添加此功能的討論。 原生辨別聯合將使定義和使用聯合類型變得更容易,無需依賴於類別層次結構。

編譯器錯誤和類型安全性

區分聯合的其中一個主要優勢是它們提供的類型安全性。由於所有可能的情況在編譯時就已知,編譯器可以確保所有情況都得到處理。 這樣可以減少運行時錯誤,使程式碼不易出錯。

例如,如果您忘記在 switch 語句中處理特定情況,編譯器將產生錯誤,提醒您解決缺少的情況。 這在處理具有多種可能情況的複雜數據結構時尤其有用。

在 C# 中使用 IronPDF 和辨别联合

C# 差異聯合(對開發者的工作機制):圖 1 - IronPDF

IronPDF 是一個 C# PDF 程式庫,幫助開發人員從 HTML 創建 PDF 文件並允許他們輕鬆修改PDF文件。 在使用 C# 處理 PDF 時,您可以將 IronPDF 與判別聯合結合,來處理不同的情境以生成或處理 PDF 文件。 例如,您可能有一個流程,可以成功生成 PDF,或遇到錯誤。 判別聯合體允許您清楚地建模此過程。 讓我們創建一個簡單的例子,使用IronPDF生成PDF,並將結果作為一個區別聯合返回。

using IronPdf;
using System;
public abstract class PdfResult
{
    private PdfResult() { }
    public sealed class Success : PdfResult
    {
        public PdfDocument Pdf { get; }
        public Success(PdfDocument pdf) => Pdf = pdf;
        public override string ToString() => "PDF generation succeeded";
    }
    public sealed class Failure : PdfResult
    {
        public string ErrorMessage { get; }
        public Failure(string errorMessage) => ErrorMessage = errorMessage;
        public override string ToString() => $"PDF generation failed: {ErrorMessage}";
    }
    public static PdfResult CreateSuccess(PdfDocument pdf) => new Success(pdf);
    public static PdfResult CreateFailure(string errorMessage) => new Failure(errorMessage);
}
public class PdfGenerator
{
    public PdfResult GeneratePdf(string htmlContent)
    {
        try
        {
            var renderer = new ChromePdfRenderer();
            var pdf = renderer.RenderHtmlAsPdf(htmlContent);
            return PdfResult.CreateSuccess(pdf);
        }
        catch (Exception ex)
        {
            return PdfResult.CreateFailure(ex.Message);
        }
    }
}
using IronPdf;
using System;
public abstract class PdfResult
{
    private PdfResult() { }
    public sealed class Success : PdfResult
    {
        public PdfDocument Pdf { get; }
        public Success(PdfDocument pdf) => Pdf = pdf;
        public override string ToString() => "PDF generation succeeded";
    }
    public sealed class Failure : PdfResult
    {
        public string ErrorMessage { get; }
        public Failure(string errorMessage) => ErrorMessage = errorMessage;
        public override string ToString() => $"PDF generation failed: {ErrorMessage}";
    }
    public static PdfResult CreateSuccess(PdfDocument pdf) => new Success(pdf);
    public static PdfResult CreateFailure(string errorMessage) => new Failure(errorMessage);
}
public class PdfGenerator
{
    public PdfResult GeneratePdf(string htmlContent)
    {
        try
        {
            var renderer = new ChromePdfRenderer();
            var pdf = renderer.RenderHtmlAsPdf(htmlContent);
            return PdfResult.CreateSuccess(pdf);
        }
        catch (Exception ex)
        {
            return PdfResult.CreateFailure(ex.Message);
        }
    }
}

PdfResult 類別表示具有兩種情況的區分聯合:成功和失敗。 成功的情況包含一個 PdfDocument,而失敗的情況則存有一個錯誤信息。 GeneratePdf 方法接受一個 HTML 字串,嘗試使用 IronPDF 生成 PDF,並將結果作為 PdfResult 返回。 如果 PDF 生成成功,將返回包含生成的 PDF 的成功案例。 如果發生異常,它將回傳失敗案例和錯誤訊息。

結論

C# 列舉聯合(對開發人員的運作方式):圖 2 - 授權

C# 中的歧視性聯合提供了一種強大且靈活的方式來建模具有多種可能情況的數據。 雖然 C# 不支援辨別聯合,但您可以使用類別繼承、模式匹配和其他技術來模擬它們。 生成的代碼更具有類型安全性,減少錯誤,且更易於維護。

IronPDF 提供一個免費試用以便在不需預付任何成本的情況下,幫助您了解軟體的使用感受。 您可以探索所有功能,看看它們如何符合您的需求。 試用之後,授權價格開始於 $749。

Kannaopat Udonpant
坎納帕特·烏頓潘
軟體工程師
在成為軟體工程師之前,Kannapat 在日本北海道大學完成了環境資源博士學位。在攻讀學位期間,Kannapat 也成為了車輛機器人實驗室的成員,該實驗室隸屬於生物生產工程學系。2022 年,他利用自己的 C# 技能,加入了 Iron Software 的工程團隊,專注於 IronPDF 的開發。Kannapat 珍視這份工作,因為他可以直接向負責撰寫大部分 IronPDF 程式碼的開發人員學習。除了同儕學習外,Kannapat 還享受在 Iron Software 工作的社交方面。當他不在撰寫程式碼或文件時,Kannapat 通常會在 PS5 上玩遊戲或重看《最後生還者》。
< 上一頁
C# HttpClient(開發人員如何使用)
下一個 >
C# 新的 GUID(如何為開發者運作)