Przejdź do treści stopki
POMOC .NET

Generiki w języku C# (jak działają dla programistów)

C# generics wprowadzają sposób na projektowanie klas, metod, interfejsów i delegatów, gdzie typ danych, którymi zarządzają, może być określony jako parametr. Ten koncept, znany jako parametr typu generycznego, pozwala na tworzenie elastycznych i wielokrotnego użytku komponentów kodu. Korzystając z generics, możesz zmaksymalizować wielokrotne użycie kodu, bezpieczeństwo typów oraz wydajność. Na przykład klasa generyczna może być zdefiniowana raz, ale zainstalowana z różnymi typami danych, oferując wszechstronność i integralność typów. W tym artykule omówimy podstawy C# Generics i funkcje biblioteki IronPDF do manipulacji PDF.

Podstawy Klas Generycznych

Klasa generyczna w C# to szablon do tworzenia klasy z miejscem na typ, którym zawiera lub na którym operuje. To miejsce, często oznaczane jako T, reprezentuje parametr typu, który jest określony podczas instancjacji klasy. Możemy tworzyć klasy generyczne z parametrem typu T, które obsługują różne typy danych. Klasy generyczne są szczególnie przydatne dla klas kolekcyjnych, takich jak listy, kolejki i tablice haszujące, ponieważ mogą przechowywać dowolny typ danych, zapewniając bezpieczeństwo typów i zmniejszając potrzebę rzutowania.

Prosty Przykład Klasy Generycznej

Rozważmy klasę generyczną o nazwie Box, zaprojektowaną do przechowywania wartości dowolnego typu:

public class Box<t>
{
    private T data;

    public Box(T data)
    {
        this.data = data;
    }

    public T Data
    {
        get { return data; }
    }
}
public class Box<t>
{
    private T data;

    public Box(T data)
    {
        this.data = data;
    }

    public T Data
    {
        get { return data; }
    }
}
Public Class Box(Of T)
    Private data As T

    Public Sub New(data As T)
        Me.data = data
    End Sub

    Public ReadOnly Property Data As T
        Get
            Return data
        End Get
    End Property
End Class
$vbLabelText   $csharpLabel

Aby użyć tej klasy, tworzysz instancję, określając rzeczywisty typ dla T:

Box<int> integerBox = new Box<int>(123);
Box<string> stringBox = new Box<string>("Hello");
Box<int> integerBox = new Box<int>(123);
Box<string> stringBox = new Box<string>("Hello");
Dim integerBox As New Box(Of Integer)(123)
Dim stringBox As New Box(Of String)("Hello")
$vbLabelText   $csharpLabel

Ten kod ilustruje, jak jedna klasa (Box) może adaptować się, aby przechowywać różne typy danych (int, string), pokazując moc generics dla wielokrotnego użycia kodu i bezpieczeństwa typów.

Implementowanie Metod Generycznych

Metody generyczne są podobne do klas generycznych, ale są definiowane z parametrami typu na poziomie metody. Pozwala to na tworzenie metod, które mogą operować na różnych typach, będąc zdefiniowanym w klasie niegenerycznej lub generycznej.

Przykład Metody Generycznej

Oto metoda, która zamienia dwa elementy w tablicy dowolnego typu:

public class Utility
{
    // Swaps two elements by reference using generics
    public static void Swap<t>(ref T lhs, ref T rhs)
    {
        T temp = lhs; // Store lhs in a temporary variable
        lhs = rhs;    // Assign rhs to lhs
        rhs = temp;   // Assign temp (original lhs) to rhs
    }
}
public class Utility
{
    // Swaps two elements by reference using generics
    public static void Swap<t>(ref T lhs, ref T rhs)
    {
        T temp = lhs; // Store lhs in a temporary variable
        lhs = rhs;    // Assign rhs to lhs
        rhs = temp;   // Assign temp (original lhs) to rhs
    }
}
Public Class Utility
    ' Swaps two elements by reference using generics
    Public Shared Sub Swap(Of T)(ByRef lhs As T, ByRef rhs As T)
        Dim temp As T = lhs ' Store lhs in a temporary variable
        lhs = rhs ' Assign rhs to lhs
        rhs = temp ' Assign temp (original lhs) to rhs
    End Sub
End Class
$vbLabelText   $csharpLabel

Użycie powyższej metody może wyglądać następująco:

int a = 1, b = 2;
Utility.Swap<int>(ref a, ref b);

string first = "world", second = "hello";
Utility.Swap(ref first, ref second);
int a = 1, b = 2;
Utility.Swap<int>(ref a, ref b);

string first = "world", second = "hello";
Utility.Swap(ref first, ref second);
Dim a As Integer = 1, b As Integer = 2
Utility.Swap(Of Integer)(a, b)

Dim first As String = "world", second As String = "hello"
Utility.Swap(first, second)
$vbLabelText   $csharpLabel

Badanie Interfejsów Generycznych i Delegatów

Interfejsy i delegaty generyczne pozwalają na definiowanie kontraktów i metod wywołania zwrotnego, które mogą operować na dowolnym typie. Implementacja generycznego interfejsu lub użycie generycznego delegata w twojej klasie lub metodzie zwiększa elastyczność i wielokrotne użycie kodu.

Przykład Interfejsu Generycznego

Generyczny interfejs repozytorium dla operacji dostępu do danych może wyglądać tak:

public interface IRepository<t>
{
    void Add(T item);
    T GetById(int id);
    IEnumerable<t> GetAll();
}
public interface IRepository<t>
{
    void Add(T item);
    T GetById(int id);
    IEnumerable<t> GetAll();
}
Public Interface IRepository(Of T)
    Sub Add(item As T)
    Function GetById(id As Integer) As T
    Function GetAll() As IEnumerable(Of T)
End Interface
$vbLabelText   $csharpLabel

Ten interfejs może być zaimplementowany przez dowolną klasę do obsługi konkretnych typów danych, umożliwiając spójne wzorce dostępu do danych dla różnych typów.

Przykład Delegata Generycznego

Generyczny delegat mógłby być użyty do zdefiniowania typu możliwość wywołania zwrotnego:

public delegate void Action<t>(T item);
public delegate void Action<t>(T item);
Public Delegate Sub Action(Of T)(item As T)
$vbLabelText   $csharpLabel

Wykorzystanie Kolekcji Generycznych

Klasy kolekcji generycznych, takie jak List, Dictionary<TKey, TValue>, i inne w przestrzeni nazw System.Collections.Generic, oferują typ-bezpieczne, wydajne kolekcje do przechowywania i manipulowania danymi dowolnego specyficznego typu. Te kolekcje są lepsze od ich niegenerycznych odpowiedników, ponieważ eliminują potrzebę rzutowania i zmniejszają błędy w czasie wykonywania.

List<string> names = new List<string>();
names.Add("Alice");
names.Add("Bob");

Dictionary<int, string> keyValuePairs = new Dictionary<int, string>();
keyValuePairs.Add(1, "One");
keyValuePairs.Add(2, "Two");
List<string> names = new List<string>();
names.Add("Alice");
names.Add("Bob");

Dictionary<int, string> keyValuePairs = new Dictionary<int, string>();
keyValuePairs.Add(1, "One");
keyValuePairs.Add(2, "Two");
Dim names As New List(Of String)()
names.Add("Alice")
names.Add("Bob")

Dim keyValuePairs As New Dictionary(Of Integer, String)()
keyValuePairs.Add(1, "One")
keyValuePairs.Add(2, "Two")
$vbLabelText   $csharpLabel

Tworzenie Własnych Typów Generycznych

Poza korzystaniem z wbudowanych typów generycznych, możesz tworzyć własne, aby ująć operacje, które są wspólne dla różnych typów danych, ale wymagają obsługi w sposób specyficzny dla typu. To podejście jest szczególnie przydatne podczas budowania bibliotek, frameworków lub narzędzi, które mają być używane z różnymi typami danych.

Przykład Własnego Typu Generycznego

Rozważmy klasę generyczną Result, która kapsułuje wyniki operacji razem z flagą sukcesu i opcjonalną wiadomością:

public class Result<t>
{
    public bool Success { get; private set; }
    public T Data { get; private set; }
    public string Message { get; private set; }

    public Result(bool success, T data, string message = "")
    {
        Success = success;
        Data = data;
        Message = message;
    }
}
public class Result<t>
{
    public bool Success { get; private set; }
    public T Data { get; private set; }
    public string Message { get; private set; }

    public Result(bool success, T data, string message = "")
    {
        Success = success;
        Data = data;
        Message = message;
    }
}
Public Class Result(Of T)
    Public ReadOnly Property Success As Boolean
    Public ReadOnly Property Data As T
    Public ReadOnly Property Message As String

    Public Sub New(success As Boolean, data As T, Optional message As String = "")
        Me.Success = success
        Me.Data = data
        Me.Message = message
    End Sub
End Class
$vbLabelText   $csharpLabel

IronPDF: Biblioteka PDF w C

IronPDF to wszechstronna biblioteka zaprojektowana dla deweloperów .NET do tworzenia, edycji i ekstrakcji dokumentów PDF w ich aplikacjach. IronPDF pomaga w generowaniu PDF z HTML, edycji istniejących PDF, konwersji PDF na obrazy i wielu innych. Chociaż IronPDF sam w sobie nie jest oparty na generykach, zrozumienie, jak wchodzić w interakcję z tą biblioteką w środowisku C#, może znacznie zwiększyć możliwości zarządzania dokumentami aplikacji.

Przykład Kodowania: Użycie słowa kluczowego virtual z IronPDF

Idea stojąca za użyciem generics tutaj to stworzenie metody wielokrotnego użytku, która może generować PDF z dowolnego podanego ciągu HTML. Ta metoda będzie generyczna, pozwalając nam specyfikować różne typy metadanych lub konfiguracji w miarę potrzeby.

Najpierw zdefiniujmy prostą klasę generyczną, która będzie zawierać opcje generowania naszego PDF. Dla celów demonstracyjnych ta klasa będzie podstawowa, ale możesz ją rozszerzyć o więcej właściwości, aby spełnić swoje potrzeby.

public class PdfOptions<t>
{
    public T Metadata { get; set; }
    public string HtmlContent { get; set; }
}
public class PdfOptions<t>
{
    public T Metadata { get; set; }
    public string HtmlContent { get; set; }
}
Public Class PdfOptions(Of T)
    Public Property Metadata As T
    Public Property HtmlContent As String
End Class
$vbLabelText   $csharpLabel

Teraz stwórzmy metodę statyczną, która generuje PDF przy użyciu IronPDF, korzystając z naszej klasy PdfOptions. Ta metoda przyjmie instancję PdfOptions jako parametr, demonstrując użycie generics w działaniu.

using IronPdf; // Make sure to include the necessary namespace for IronPDF

public static class PdfGenerator
{
    // Generates a PDF from provided HTML content and options
    public static void GeneratePdf<t>(PdfOptions<t> options)
    {
        // Initialize the IronPDF HtmlToPdf renderer
        var renderer = new ChromePdfRenderer();

        // Optional: Apply any renderer options here, for example, setting the paper size
        renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;

        // Generate the PDF from HTML content
        var pdfDocument = renderer.RenderHtmlAsPdf(options.HtmlContent);

        // Optional: Here, you can use options.Metadata in some way, depending on your generic type T
        // For simplicity, we're just printing the metadata to console if it's of type string
        if (options.Metadata is string metadataString)
        {
            Console.WriteLine($"Metadata: {metadataString}");
        }

        // Save the PDF to a file
        var fileName = $"GeneratedPdf_{DateTime.Now.Ticks}.pdf";
        pdfDocument.SaveAs(fileName);
        Console.WriteLine($"PDF generated and saved as {fileName}");
    }
}
using IronPdf; // Make sure to include the necessary namespace for IronPDF

public static class PdfGenerator
{
    // Generates a PDF from provided HTML content and options
    public static void GeneratePdf<t>(PdfOptions<t> options)
    {
        // Initialize the IronPDF HtmlToPdf renderer
        var renderer = new ChromePdfRenderer();

        // Optional: Apply any renderer options here, for example, setting the paper size
        renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;

        // Generate the PDF from HTML content
        var pdfDocument = renderer.RenderHtmlAsPdf(options.HtmlContent);

        // Optional: Here, you can use options.Metadata in some way, depending on your generic type T
        // For simplicity, we're just printing the metadata to console if it's of type string
        if (options.Metadata is string metadataString)
        {
            Console.WriteLine($"Metadata: {metadataString}");
        }

        // Save the PDF to a file
        var fileName = $"GeneratedPdf_{DateTime.Now.Ticks}.pdf";
        pdfDocument.SaveAs(fileName);
        Console.WriteLine($"PDF generated and saved as {fileName}");
    }
}
Imports IronPdf ' Make sure to include the necessary namespace for IronPDF

Public Module PdfGenerator
    ' Generates a PDF from provided HTML content and options
    Public Sub GeneratePdf(Of T)(options As PdfOptions(Of T))
        ' Initialize the IronPDF HtmlToPdf renderer
        Dim renderer As New ChromePdfRenderer()

        ' Optional: Apply any renderer options here, for example, setting the paper size
        renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4

        ' Generate the PDF from HTML content
        Dim pdfDocument = renderer.RenderHtmlAsPdf(options.HtmlContent)

        ' Optional: Here, you can use options.Metadata in some way, depending on your generic type T
        ' For simplicity, we're just printing the metadata to console if it's of type string
        If TypeOf options.Metadata Is String Then
            Dim metadataString As String = CType(options.Metadata, String)
            Console.WriteLine($"Metadata: {metadataString}")
        End If

        ' Save the PDF to a file
        Dim fileName As String = $"GeneratedPdf_{DateTime.Now.Ticks}.pdf"
        pdfDocument.SaveAs(fileName)
        Console.WriteLine($"PDF generated and saved as {fileName}")
    End Sub
End Module
$vbLabelText   $csharpLabel

Na koniec użyjmy naszej klasy PdfGenerator do wygenerowania dokumentu PDF. W tym przykładzie właściwość Metadata mogłaby być ciągiem zawierającym tytuł lub jakąkolwiek inną informację, którą uznasz za istotną.

class Program
{
    static void Main(string[] args)
    {
        // Set the license key for IronPDF if needed
        License.LicenseKey = "Your-License-Key-Here";

        // Create PDF options with HTML content and metadata
        var options = new PdfOptions<string>
        {
            HtmlContent = "<h1>Hello, World!</h1><p>This is a test PDF document generated from HTML.</p>",
            Metadata = "Test PDF Title"
        };

        // Generate the PDF using the specified options
        PdfGenerator.GeneratePdf(options);
    }
}
class Program
{
    static void Main(string[] args)
    {
        // Set the license key for IronPDF if needed
        License.LicenseKey = "Your-License-Key-Here";

        // Create PDF options with HTML content and metadata
        var options = new PdfOptions<string>
        {
            HtmlContent = "<h1>Hello, World!</h1><p>This is a test PDF document generated from HTML.</p>",
            Metadata = "Test PDF Title"
        };

        // Generate the PDF using the specified options
        PdfGenerator.GeneratePdf(options);
    }
}
Friend Class Program
	Shared Sub Main(ByVal args() As String)
		' Set the license key for IronPDF if needed
		License.LicenseKey = "Your-License-Key-Here"

		' Create PDF options with HTML content and metadata
		Dim options = New PdfOptions(Of String) With {
			.HtmlContent = "<h1>Hello, World!</h1><p>This is a test PDF document generated from HTML.</p>",
			.Metadata = "Test PDF Title"
		}

		' Generate the PDF using the specified options
		PdfGenerator.GeneratePdf(options)
	End Sub
End Class
$vbLabelText   $csharpLabel

Ten przykład ilustruje podstawy integracji IronPDF z C# Generics, zapewniając elastyczny sposób generowania PDF z treści HTML przy jednoczesnym umożliwieniu dostosowywalnych metadanych lub konfiguracji za pomocą generycznej klasy PdfOptions. Możesz rozszerzyć to, dodając bardziej wyrafinowane opcje i konfiguracje rendererów w miarę potrzeby w swojej aplikacji.

C# Generics (Jak To Działa Dla Deweloperów): Rysunek 1 - Przykład wynikowego kodu wykorzystujący generics do tworzenia dokumentu PDF z ciągu HTML przy użyciu IronPDF

Wniosek

C# Generics (Jak To Działa Dla Deweloperów): Rysunek 2 - Strona licencyjna IronPDF

C# generics to potężne narzędzie do tworzenia wysokiej jakości, wielokrotnego użytku i bezpiecznego typu kodu. Zrozumienie i stosowanie klas generycznych, metod, interfejsów i delegatów, pozwala na pisanie kodu, który jest bardziej adaptacyjny i łatwiejszy do utrzymania. Generics nie tylko umożliwiają ponowne użycie kodu dla różnych typów danych, ale także zapewniają kontrolę typu w czasie kompilacji, co redukuje błędy w czasie wykonywania i poprawia ogólną jakość kodu. IronPDF oferuje darmową wersję próbną swoich narzędzi do biblioteki PDF z kosztami od $799 w górę.

Często Zadawane Pytania

Czym są generyki w C#?

Generyki w C# wprowadzają sposób projektowania klas, metod, interfejsów i delegatów przy użyciu parametru typu. Umożliwia to tworzenie elastycznych i wielokrotnego użytku komponentów kodu, które zapewniają bezpieczeństwo typów i poprawę wydajności.

Jak działają klasy generyczne w C#?

Klasa generyczna w C# używa parametru typu, często oznaczonego jako T, który działa jako miejsce dla typu, który zawiera lub na którym operuje. To pozwala na instancjonowanie klasy z różnymi typami danych przy jednoczesnym zachowaniu bezpieczeństwa typów.

Czy możesz podać przykład klasy generycznej w C#?

Tak, prostym przykładem jest klasa Box, która przechowuje wartość dowolnego typu. Możesz tworzyć instancje takie jak Box lub Box, aby przechowywać różne typy danych w tej samej klasie.

Co to jest metoda generyczna w C#?

Metoda generyczna jest zdefiniowana z parametrami typu na poziomie metody, co pozwala jej na operowanie na różnych typach. Może być częścią klasy niegenerycznej lub generycznej, zapewniając elastyczność w projektowaniu metody.

Jak można używać interfejsów i delegatów generycznych w C#?

Interfejsy i delegaty generyczne umożliwiają definiowanie kontraktów i metod zwrotnych, które mogą działać z dowolnym typem, co zwiększa elastyczność i możliwość ponownego użycia kodu.

Jakie są korzyści z używania generycznych kolekcji w C#?

Generyczne kolekcje, takie jak List i Dictionary, oferują bezpieczne typowo i wydajne przechowywanie dla dowolnego konkretnego typu, eliminując potrzebę rzutowania i zmniejszając błędy w czasie wykonywania.

Jak mogę tworzyć niestandardowe typy generyczne w C#?

Możesz tworzyć niestandardowe typy generyczne, aby kapsułkować operacje powszechne dla różnych typów danych, ale obsługiwane w sposób specyficzny dla typu, co jest użyteczne do budowy bibliotek lub narzędzi.

Jak generyki w C# mogą poprawić generację PDF w .NET?

Generyki w C# mogą być używane z biblioteką PDF do tworzenia elastycznych i wielokrotnego użytku komponentów. Na przykład, klasa PdfOptions może być użyta do przechowywania opcji generowania PDF, co pokazuje adaptacyjność generyków w zadaniach związanych z PDF.

Jak biblioteka PDF może być używana z generykami w C#?

Biblioteka PDF, taka jak IronPDF, może wykorzystać generyki w C# do zwiększenia swojej funkcjonalności. Na przykład, metoda generyczna mogłaby być użyta do konwersji HTML do PDF, zapewniając elastyczne podejście do generacji dokumentów.

Jakie są zalety używania generyków w C#?

Generyki w C# pozwalają na wielokrotne użycie kodu dla różnych typów danych, zapewniają sprawdzanie typów w czasie kompilacji, zmniejszają błędy w czasie wykonywania i poprawiają ogólną jakość kodu. Umożliwiają pisanie elastycznego i łatwego do utrzymania kodu.

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ą...

Czytaj więcej

Zespol wsparcia Iron

Jestesmy online 24 godziny, 5 dni w tygodniu.
Czat
Email
Zadzwon do mnie