Przejdź do treści stopki
POMOC .NET

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

Potegi C# wprowadzają sposob projektowania klas, metod, interfejsow i delegatow, w ktorym typ danych, ktore zarządzają, może być okreslony jako parametr. Ten koncept, znany jako parametr typu ogolnego, pozwala na tworzenie elastycznych i ponownie używalnych komponentow kodu. Używając ogolnych typow, można zmaksymalizowac ponowne użycie kodu, bezpieczeństwo typow i wydajność. Na przykład ogolna klasa może być zdefiniowana raz, ale instancjonowana z różnymi typami danych, oferujac wszechstronnosc i integralnosc typow. W tym artykułe poznamy podstawy potegi C# oraz funkcje biblioteki IronPDF do obrobki plików PDF.

Podstawy ogolnych klas

Ogolna klasa w C# to szablon do tworzenia klasy z miejscem na typ, ktory zawiera lub na ktory działa. To miejsce, często oznaczane przez T, odpowaida parametrowi typu, ktory jest specyfikowany podczas tworzenia instancji klasy. Możemy tworzyć ogolne klasy z parametrem typu T do obsługi różnych typow danych. Ogolne klasy sa szczegółnie przydatne dla klas kolekcji, takich jak listy, kolejki i tablice mieszajace, poniewaz mogą przechowywać dowolny typ danych, zapewniając bezpieczeństwo typow i redukujac potrzebe rzutowania.

Prosty przykład ogolnej klasy

Rozwazmy ogolna klase o nazwie Box, która jest zaprojektowana do przechowywania wartosci 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 uzyc tej klasy, należy stworzyć instancje, specyfikujac 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) moze dostosowac sie do przechowywania roznych typow danych (int, string), pokazujac moc generykow dla ponownego uzycia kodu i bezpieczenstwa typow.

Implementacja ogolnych metod

Ogolne metody sa podobne do ogolnych klas, ale sa definiowane z parametrami typu na poziomie metody. Umozliwia to tworzenie metod, ktore mogą działać na różnych typach, będąc zdefiniowane w klasie nieogolnej lub ogolnej.

Przyklad ogolnej metody

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

Uzycie powyzszej metody może wyglądac nastepujaco:

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 ogolnych interfejsow i delegatow

Ogolne interfejsy i delegaty pozwalają na definiowanie kontraktow i metod zwrotnych, ktore mogą działać z dowolnym typem. Wdrozenie ogolnego interfejsu lub użycie ogolnego delegata w swojej klasie lub metodzie zwieksza elastycznosc i ponowne używanie kodu.

Przyklad ogolnego interfejsu

Ogolny interfejs repozytorium dla operacji dostepu do danych może wyglądac nastepujaco:

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 kazda klase, aby obsługiwac okreslone typy danych, pozwalając na spojnosc wzorcow dostepu do danych w różnych typach.

Przyklad ogolnego delegata

Ogolny delegat może być uzyty do zdefiniowania bezpiecznego typowo wezwania 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

Uzywanie ogolnych kolekcji

Generyczne klasy kolekcji, takie jak List, Dictionary<TKey, TValue> i inne w przestrzeni nazw System.Collections.Generic, oferuja bezpieczne typowo, wydajne kolekcje do przechowywania i manipulowania danymi o dowolnym konkretnym typie. Te kolekcje sa lepsze od ich nieogolnych odpowiednikow, poniewaz eliminuja potrzebe rzutowania i redukuja 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 ogolnych typow

Poza użyciem wbudowanych ogolnych typow można stworzyć własne, aby zainkapsulowac operacje, ktore sa wspolne dla różnych typow danych, ale trzeba je obsługiwac w sposob typowy. To podejście jest wyjątkówo uzyteczne przy budowie bibliotek, frameworkow lub narzędzi, ktore maja być używane z różnych typami danych.

Przyklad własnego ogolnego typu

Rozwazmy ogolna klase Result, która kapsuluje wyniki operacji wraz z flaga powodzenia i opcjonalnym komunikatem:

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 dla języka C

IronPDF to wszechstronna biblioteka zaprojektowana dla programistów .NET do tworzenia, edycji i ekstrakcji dokumentów PDF w ramach ich aplikacji. IronPDF pomaga w generowaniu PDF z HTML, edytowaniu istniejących PDF, konwersji PDF na obrazy i wielu innych. Chociaż IronPDF sam w sobie nie opiera sie na ogolnych typach, zrozumienie, jak wchodzic w interakcje z ta biblioteka w środowisku C#, może znacznie zwiększyć możliwości zarządzania dokumentami w twojej aplikacji.

Przyklad kodu: Uzycie slowa kluczowego virtual z IronPDF

Idea użycia tutaj ogolnych typow polega na stworzeniu wielokrotnie używalnej metody, która może generować PDF z dowolnego podanego ciągu HTML. Ta metoda będzie ogolna, pozwalając okreslac różne typy metadanych lub konfiguracji w razie potrzeby.

Najpierw zdefiniujmy prosta ogolna klase, która będzie przechowywać opcje generowania PDF. Do celow demonstracyjnych, ta klasa będzie podstawowa, ale można ja rozszerzyc o więcej właściwości, aby dopasowac do potrzeb.

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 stworzmy statyczna metode generujaca PDF uzywajac IronPDF, wykorzystujac nasza klase PdfOptions. Ta metoda przyjmie instancje PdfOptions jako parametr, pokazujac zastosowanie generykow w praktyce.

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, skorzystajmy z naszej klasy PdfGenerator do wygenerowania dokumentu PDF. W tym przykładzie właściwość Metadata może być napisanym ciągiem tekstowym zawierajacym tytuł lub inne informacje uznane za istotne.

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 przyklad ilustruje podstawy integracji IronPDF z C# Generykami, oferujac elastyczny sposob generowania PDFow z tresci HTML przy jednoczesnym umozliwieniu dostosowywania metadanych lub konfiguracji za pomoca generycznej klasy PdfOptions. Możesz to rozwinac, dodajac bardziej zaawansowane opcje i konfiguracje rendererow w zależności od potrzeb swojej aplikacji.

C# Generics (Jak to dziala dla programistow): Rysunek 1 - Przykladowy wynik kodu wykorzystujacego generyki do tworzenia dokumentu PDF z lancucha HTML za pomoca IronPDF

Wnioski

C# Generics (Jak to dziala dla programistow): Rysunek 2 - strona licencji IronPDF

Potegi w C# sa poteznym narzędziem do rozwijania wysokiej jakosci, wielokrotnie używalnego i bezpiecznego typowo kodu. Poprzez zrozumienie i zastosowanie ogolnych klas, metod, interfejsow i delegatow można pisac kod, ktory jest bardziej dostosowalny i łatwiejszy do utrzymania. Ogolne typy nie tylko umożliwiaja ponowne użycie kodu z różnych typach danych, ale również zapewniają sprawdzanie typow podczas kompilacji, co redukuje błędy w czasie wykonywania i poprawia ogolna jakosc kodu. IronPDF oferuje bezplatna wersje probna swoich narzedzi biblioteki PDF, z kosztami od $999 wzwyz.

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, prosty przykład to klasa Box, która przechowuje wartość dowolnego typu. Można tworzyć instancje jak Box lub Box, aby przechowywać różne typy danych, używając tej samej klasy.

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#?

Genericszne kolekcje jak List i Dictionary oferują bezpieczne typy i efektywne przechowywanie dla dowolnego określonego typu, eliminując potrzebę konwersji i ograniczają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?

Genericsy w C# mogą być stosowane z biblioteką PDF do tworzenia elastycznych i wielokrotnego użytku komponentów. Na przykład, klasa PdfOptions może być używana do przechowywania opcji generowania PDF, co pokazuje adaptacyjność genericsó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

Zespół wsparcia Iron

Jesteśmy online 24 godziny, 5 dni w tygodniu.
Czat
E-mail
Zadzwoń do mnie