IRONSOFTWAREHOME
AKTUALNOŚCI DLA PROGRAMISTÓW

C# Unie dyskryminacyjne (Jak to działa dla programistów)

Jacob Mellor, Dyrektor Technologiczny @ Team Iron
Jacob Mellor
Updated: 28 lipca 2025

Unie dyskryminowane, znane również jako unie tagowane lub sumaryczne, są potężnym narzędziem do modelowania danych, które mogą przyjmować różne formy, ale z dobrze zdefiniowanymi i ograniczonymi możliwymi przypadkami. Chociaż C# nie posiada natywnych unii dyskryminowanych, jak niektóre inne języki (np. F# lub Rust), można symulować unie dyskryminowane przy użyciu kilku technik w tym języku. W tym poradniku zgłębimy unie dyskryminowane, jak je zaimplementować w C#, oraz ich praktyczne zastosowanie z biblioteka IronPDF.

Co to jest unia dyskryminowana?

W prostych słowach, unia dyskryminowana to typ, który może przechowywać jedną z kilku z góry określonych form lub wartości. Zapewnia sposób na stworzenie bezpiecznej pod względem typów struktury, która kapsułuje różne typy lub wartości, zapewniając jednocześnie, że tylko prawidłowe przypadki są obsługiwane na etapie kompilacji.

Wyobraź sobie scenariusz, w którym chcesz przedstawić wynik operacji. Operacja może zakończyć się sukcesem, zwracając dane, lub zakończyć się niepowodzeniem, zwracając komunikat o błędzie. Unia dyskryminowana pozwoliłaby ci przedstawić te dwa możliwe wyniki w jednym typie.

Example: Simulating Discriminated Union in C#

Oto przykład, jak można symulować unię dyskryminowaną w C# przy użyciu struktury klasowej:

// Define an abstract base class representing the operation result.
public abstract class OperationResult<t>
{
    // Private constructor to ensure the class cannot be instantiated directly.
    private OperationResult() { }

    // Nested class representing a successful operation result.
    public sealed class Success : OperationResult<t>
    {
        public T Value { get; }
        
        public Success(T value) => Value = value;

        public override string ToString() => $"Success: {Value}";
    }

    // Nested class representing a failed operation result.
    public sealed class Failure : OperationResult<t>
    {
        public string Error { get; }
        
        public Failure(string error) => Error = error;

        public override string ToString() => $"Failure: {Error}";
    }

    // Factory method to create a successful operation result.
    public static OperationResult<t> CreateSuccess(T value) => new Success(value);

    // Factory method to create a failed operation result.
    public static OperationResult<t> CreateFailure(string error) => new Failure(error);
}
C#

W tym przykładzie, OperationResult<t> jest abstrakcyjną klasą, która reprezentuje nasz typ unii rozróżnialnej. Może być albo Success z wartością typu T, albo Failure z komunikatem błędu. Prywatny konstruktor zapewnia, że instancje takiej klasy mogą być tworzone tylko poprzez z góry określone przypadki.

Użycie dopasowywania wzorców z uniami dyskryminowanymi

C# zapewnia potężne możliwości dopasowywania wzorców, które dobrze współpracują z uniami dyskryminowanymi. Rozszerzmy nasz przykład OperationResult<t> o metodę, która obsługuje różne przypadki przy użyciu wyrażenia switch.

// Method to handle the result using pattern matching.
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")
    };

Wyrażenie switch tutaj obsługuje zarówno przypadki Success jak i Failure klasy OperationResult<int>. To zapewnia, że wszystkie możliwe przypadki są obsługiwane na etapie kompilacji, zapewniając bezpieczeństwo typów i zmniejszając ryzyko błędów w czasie wykonania.

Metody rozszerzające dla unii dyskryminowanych

Możesz rozszerzyć funkcjonalność unii dyskryminowanych przy użyciu metod rozszerzających. Na przykład, stwórzmy metodę rozszerzoną dla naszego OperationResult<t>, aby określić, czy wynik jest sukcesem:

// Static class to hold extension methods for OperationResult<t>.
public static class OperationResultExtensions
{
    // Extension method to check if the operation result indicates success. 
    public static bool IsSuccess<t>(this OperationResult<t> result) =>
        result is OperationResult<t>.Success;
}

Ta metoda statyczna sprawdza, czy wynik jest instancją przypadku Success.

Native Support for Discriminated Unions in C#

C# nie posiada natywnego wsparcia dla unii dyskryminowanych, jak niektóre inne języki, ale w społeczności trwają dyskusje na temat dodania takiej funkcji. Natywne unie dyskryminowane ułatwiłyby definiowanie i pracę z typami unii bez konieczności polegania na hierarchiach klas.

Błędy kompilatora i bezpieczeństwo typów

Jedną z kluczowych zalet unii dyskryminowanych jest bezpieczeństwo typów, które zapewniają. Ponieważ wszystkie możliwe przypadki są znane na etapie kompilacji, kompilator może wymusić, że wszystkie przypadki są obsługiwane. To prowadzi do mniejszej liczby błędów w czasie wykonania i czyni kod mniej podatnym na błędy.

Na przykład, jeśli zapomnisz obsłużyć konkretny przypadek w instrukcji switch, kompilator wygeneruje błąd, nakłaniając cię do obsługi brakującego przypadku. Jest to szczególnie przydatne przy pracy ze złożonymi strukturami danych z wieloma możliwymi przypadkami.

Using IronPDF with Discriminated Unions in C#

C# Unia Rozróżnialna (Jak to działa dla programistów): Rysunek 1 - IronPDF

IronPDF to biblioteka PDF dla C#, która pomaga programistom tworzyć pliki PDF z HTML i umożliwia im modyfikowanie plików PDF bez problemu. Podczas pracy z plikami PDF w C#, możesz zintegrować IronPDF z uniami dyskryminowanymi, aby obsłużyć różne scenariusze przy generowaniu lub przetwarzaniu plików PDF. Na przykład, możesz mieć proces, który albo z powodzeniem generuje plik PDF, albo napotyka błąd. Unie dyskryminowane pozwalają jasno modelować ten proces. Stwórzmy prosty przykład, w którym generujemy plik PDF przy użyciu IronPDF i zwracamy wynik jako unię dyskryminowaną.

// Using directives for necessary namespaces.
using IronPdf;
using System;

// Define an abstract base class representing the PDF generation result.
public abstract class PdfResult
{
    // Private constructor to ensure the class cannot be instantiated directly.
    private PdfResult() { }

    // Nested class representing a successful PDF generation result.
    public sealed class Success : PdfResult
    {
        public PdfDocument Pdf { get; }
        
        public Success(PdfDocument pdf) => Pdf = pdf;

        public override string ToString() => "PDF generation succeeded";
    }

    // Nested class representing a failed PDF generation result.
    public sealed class Failure : PdfResult
    {
        public string ErrorMessage { get; }
        
        public Failure(string errorMessage) => ErrorMessage = errorMessage;

        public override string ToString() => $"PDF generation failed: {ErrorMessage}";
    }

    // Factory method to create a successful PDF result.
    public static PdfResult CreateSuccess(PdfDocument pdf) => new Success(pdf);

    // Factory method to create a failed PDF result.
    public static PdfResult CreateFailure(string errorMessage) => new Failure(errorMessage);
}

// Class to generate PDFs using IronPDF.
public class PdfGenerator
{
    // Method to generate a PDF from HTML content and return the result as a PdfResult.
    public PdfResult GeneratePdf(string htmlContent)
    {
        try
        {
            // Create a new ChromePdfRenderer instance.
            var renderer = new ChromePdfRenderer();

            // Attempt to render the HTML content as a PDF.
            var pdf = renderer.RenderHtmlAsPdf(htmlContent);

            // Return a success result with the generated PDF.
            return PdfResult.CreateSuccess(pdf);
        }
        catch (Exception ex)
        {
            // Return a failure result with the error message if an exception occurs.
            return PdfResult.CreateFailure(ex.Message);
        }
    }
}

Klasa PdfResult reprezentuje unię rozróżnialną z dwoma przypadkami: Success i Failure. Przypadek Success zawiera PdfDocument, podczas gdy przypadek Failure przechowuje komunikat błędu. Metoda GeneratePdf przyjmuje ciąg HTML, próbuje wygenerować PDF przy użyciu IronPDF i zwraca wynik jako PdfResult. Jeśli generowanie PDF się powiedzie, zwraca przypadek Success z wygenerowanym PDF. Jeśli wystąpi wyjątek, zwraca przypadek Failure z komunikatem błędu.

Wnioski

C# Unia Rozróżnialna (Jak to działa dla programistów): Rysunek 2 - Licencjonowanie

Unie dyskryminowane w C# oferują potężny i elastyczny sposób na modelowanie danych z wieloma możliwymi przypadkami. Chociaż C# nie obsługuje unii dyskryminowanych, możesz je symulować przy użyciu hierarchii klas, dopasowywania wzorców i innych technik. Efekt jest bardziej bezpieczny pod względem typów, mniej podatny na błędy i łatwiejszy w utrzymaniu.

IronPDF oferuje bezpłatną wersję próbną, aby umożliwić ci poznanie oprogramowania bez żadnych kosztów na wstępie. Możesz odkrywać wszystkie funkcje i zobaczyć, jak wpisują się w twoje potrzeby. Po okresie próbnym licencje są dostępne od $999.

Jacob Mellor, Dyrektor Technologiczny @ Team Iron
Dyrektor ds. technologii

Jacob Mellor jest Chief Technology Officer w Iron Software i wizjonerskim inżynierem, pionierem technologii C# PDF. Jako pierwotny deweloper głównej bazy kodowej Iron Software, kształtuje architekturę produktów firmy od jej początku, przekształcając ją wspólnie z CEO Cameron Rimington w firmę liczącą ponad 50 osób, obsługującą NASA, Teslę i światowe agencje rządowe.

...
Czytaj więcej

Powiązane artykuły

Key in blue circle

Uzyskaj natychmiast swój darmowy 30-dniowy Klucz Testowy.

Brak ograniczeń. 100% dostępności. Bez karty kredytowej.

bullet_checkedNie wymaga karty kredytowej ani tworzenia kontaBrak ograniczeń. 100% dostępności. Bez karty kredytowej.
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
Zarezerwuj swoje darmowe Demo na żywo
Booking Badge

Zaufane przez miliony inżynierów na całym świecie

Logotypy klientów Iron Software
Otrzymaj swoje Konsultacja Bez Zobowiązań
Wypełnij poniższy formularz lub wyślij e-mail na sales@ironsoftware.com
Twoje dane zawsze będą utrzymywane w tajemnicy.
Zaufane przez miliony inżynierów na całym świecie
Logotypy klientów Iron Software
Otrzymaj swój darmowy Klucz Próbny na 30 dni natychmiast.
Nie wymaga karty kredytowej ani tworzenia konta