.NET-HILFE

C# Generics (Wie es für Entwickler funktioniert)

C# Generics bieten eine Möglichkeit, Klassen, Methoden, Schnittstellen und Delegates zu entwerfen, bei denen der Typ der zu verwaltenden Daten als Parameter angegeben werden kann. Dieses Konzept, das als generischer Typparameter bekannt ist, ermöglicht die Erstellung flexibler und wiederverwendbarer Codekomponenten. Durch die Verwendung von Generics können Sie die Wiederverwendbarkeit des Codes, die Typsicherheit und die Leistung maximieren. So kann beispielsweise eine generische Klasse einmal definiert werden, aber mit verschiedenen Datentypen instanziiert werden, was Vielseitigkeit und Typintegrität bietet. In diesem Artikel werden wir die Grundlagen von C# Generics und die Funktionen der IronPDF-Bibliothek zur PDF-Bearbeitung kennenlernen.

Die Grundlagen der generischen Klassen

Eine generische Klasse in C# ist ein Entwurf für die Erstellung einer Klasse mit einem Platzhalter für den Typ, den sie enthält oder mit dem sie arbeitet. Dieser Platzhalter, oft mit T bezeichnet, stellt einen Typ-Parameter dar, der bei der Instanziierung der Klasse angegeben wird. Wir können generische Klassen mit dem Typ-Parameter T erstellen, um verschiedene Datentypen zu verarbeiten. Generische Klassen sind besonders nützlich für Sammlungsklassen wie Listen, Warteschlangen und Hashtabellen, da sie jeden Datentyp aufnehmen können, während die Typensicherheit gewährleistet bleibt und der Bedarf an Umwandlungen verringert wird.

Einfaches Beispiel für eine generische Klasse

Betrachten Sie eine generische Klasse namens Box, die entworfen wurde, um einen Wert beliebigen Typs zu speichern:

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)
'INSTANT VB NOTE: The field data was renamed since Visual Basic does not allow fields to have the same name as other class members:
	Private data_Conflict As T
	Public Sub New(ByVal data As T)
		Me.data_Conflict = data
	End Sub
	Public ReadOnly Property Data() As T
		Get
			Return data_Conflict
		End Get
	End Property
End Class
$vbLabelText   $csharpLabel

Um diese Klasse zu verwenden, erstellen Sie eine Instanz, indem Sie den tatsächlichen Typ für T angeben:

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

Dieser Code zeigt, wie eine einzelne Klasse (Box<T>) sich anpassen kann, um verschiedene Datentypen (int, string) zu speichern, was die Leistungsfähigkeit von Generics für Code-Wiederverwendung und Typsicherheit demonstriert.

Generische Methoden implementieren

Generische Methoden ähneln den generischen Klassen, werden aber mit Typparametern auf der Methodenebene definiert. Dies ermöglicht die Erstellung von Methoden, die auf verschiedene Typen wirken können, während sie in einer nicht-generischen oder einer generischen Klasse definiert sind.

Beispiel für eine generische Methode

Hier ist eine Methode, die zwei Elemente in einem Array beliebigen Typs vertauscht:

public class Utility
{
    public static void Swap<T>(ref T lhs, ref T rhs)
    {
        T temp = lhs;
        lhs = rhs;
        rhs = temp;
    }
}
public class Utility
{
    public static void Swap<T>(ref T lhs, ref T rhs)
    {
        T temp = lhs;
        lhs = rhs;
        rhs = temp;
    }
}
Public Class Utility
	Public Shared Sub Swap(Of T)(ByRef lhs As T, ByRef rhs As T)
		Dim temp As T = lhs
		lhs = rhs
		rhs = temp
	End Sub
End Class
$vbLabelText   $csharpLabel

Die obige Methode kann wie folgt angewendet werden:

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

Erforschung von generischen Schnittstellen und Delegaten

Generische Schnittstellen und Delegierte ermöglichen die Definition von Verträgen und Rückrufmethoden, die mit jedem Typ arbeiten können. Die Implementierung einer generischen Schnittstelle oder die Verwendung eines generischen Delegaten in Ihrer Klasse oder Methode erhöht die Flexibilität und die Wiederverwendung von Code.

Beispiel für eine allgemeine Schnittstelle

Eine generische Repository-Schnittstelle für Datenzugriffsoperationen könnte wie folgt aussehen:

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(ByVal item As T)
	Function GetById(ByVal id As Integer) As T
	Function GetAll() As IEnumerable(Of T)
End Interface
$vbLabelText   $csharpLabel

Diese Schnittstelle kann von jeder Klasse implementiert werden, um bestimmte Datentypen zu handhaben, wodurch konsistente Datenzugriffsmuster für verschiedene Typen ermöglicht werden.

Beispiel für einen generischen Delegaten

Ein generischer Delegat kann verwendet werden, um einen typsicheren Rückruf zu definieren:

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

Verwendung von generischen Sammlungen

Generische Sammlungsklassen, wie List, Dictionary<TKey, TValue> und andere im System.Collections.Generic-Namensraum, bieten typsichere, effiziente Sammlungen zum Speichern und Verarbeiten von Daten eines bestimmten Typs. Diese Sammlungen sind ihren nicht-generischen Gegenstücken überlegen, weil sie das Casting überflüssig machen und Laufzeitfehler reduzieren.

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

Benutzerdefinierte generische Typen erstellen

Neben der Verwendung eingebauter generischer Typen können Sie auch eigene Typen erstellen, um Operationen zu kapseln, die in verschiedenen Datentypen üblich sind, aber typspezifisch behandelt werden müssen. Dieser Ansatz ist besonders nützlich für die Erstellung von Bibliotheken, Frameworks oder Dienstprogrammen, die mit verschiedenen Datentypen verwendet werden sollen.

Beispiel für einen benutzerdefinierten generischen Typ

Betrachten Sie eine generische Result-Klasse, die Betriebsergebnisse zusammen mit einem Erfolgsindikator und einer optionalen Nachricht kapselt:

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)
	Private privateSuccess As Boolean
	Public Property Success() As Boolean
		Get
			Return privateSuccess
		End Get
		Private Set(ByVal value As Boolean)
			privateSuccess = value
		End Set
	End Property
	Private privateData As T
	Public Property Data() As T
		Get
			Return privateData
		End Get
		Private Set(ByVal value As T)
			privateData = value
		End Set
	End Property
	Private privateMessage As String
	Public Property Message() As String
		Get
			Return privateMessage
		End Get
		Private Set(ByVal value As String)
			privateMessage = value
		End Set
	End Property
	Public Sub New(ByVal success As Boolean, ByVal data As T, Optional ByVal message As String = "")
		Me.Success = success
		Me.Data = data
		Me.Message = message
	End Sub
End Class
$vbLabelText   $csharpLabel

IronPDF: C# PDF-Bibliothek

IronPDF ist eine umfassende Bibliothek, die für .NET-Entwickler entwickelt wurde, um PDF-Dokumente innerhalb ihrer Anwendungen zu erstellen, zu bearbeiten und zu extrahieren. IronPDF hilft bei der Erstellung von PDFs aus HTML, der Bearbeitung bestehender PDFs, der Umwandlung von PDFs in Bilder und vielem mehr. IronPDF selbst basiert zwar nicht auf Generics, aber wenn Sie verstehen, wie Sie mit dieser Bibliothek in einer C#-Umgebung interagieren können, können Sie die Möglichkeiten Ihrer Anwendung zur Dokumentenverwaltung erheblich verbessern.

Code-Beispiel: Verwendung des virtuellen Schlüsselworts mit IronPDF

Die Idee hinter der Verwendung von Generika ist es, eine wiederverwendbare Methode zu erstellen, die ein PDF aus einer beliebigen HTML-Zeichenkette erzeugen kann. Diese Methode ist generisch und ermöglicht es uns, je nach Bedarf verschiedene Arten von Metadaten oder Konfigurationen anzugeben.

Definieren wir zunächst eine einfache generische Klasse, die unsere PDF-Generierungsoptionen enthält. Zu Demonstrationszwecken wird diese Klasse einfach sein, aber Sie können sie mit weiteren Eigenschaften erweitern, um Ihren Bedürfnissen gerecht zu werden.

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

Jetzt erstellen wir eine statische Methode, die mit IronPDF über unsere PdfOptions-Klasse ein PDF generiert. Diese Methode nimmt eine Instanz von PdfOptionsals Parameter und demonstriert damit den Einsatz von Generika in Aktion.

public static class PdfGenerator
{
    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}");
    }
}
public static class PdfGenerator
{
    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}");
    }
}
Public Module PdfGenerator
	Public Sub GeneratePdf(Of T)(ByVal options As PdfOptions(Of T))
		' Initialize the IronPDF HtmlToPdf renderer
		Dim 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
		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.
		Dim tempVar As Boolean = TypeOf options.Metadata Is String
		Dim metadataString As String = If(tempVar, CStr(options.Metadata), Nothing)
		If tempVar Then
			Console.WriteLine($"Metadata: {metadataString}")
		End If
		' Save the PDF to a file
		Dim fileName = $"GeneratedPdf_{DateTime.Now.Ticks}.pdf"
		pdfDocument.SaveAs(fileName)
		Console.WriteLine($"PDF generated and saved as {fileName}")
	End Sub
End Module
$vbLabelText   $csharpLabel

Schließlich verwenden wir unsere PdfGenerator-Klasse, um ein PDF-Dokument zu erstellen. In diesem Beispiel könnte die Metadata-Eigenschaft eine Zeichenkette sein, die einen Titel oder andere relevante Informationen enthält.

class Program
{
    static void Main(string [] args)
    {
        License.LicenseKey = "License-Key";
        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"
        };
        PdfGenerator.GeneratePdf(options);
    }
}
class Program
{
    static void Main(string [] args)
    {
        License.LicenseKey = "License-Key";
        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"
        };
        PdfGenerator.GeneratePdf(options);
    }
}
Friend Class Program
	Shared Sub Main(ByVal args() As String)
		License.LicenseKey = "License-Key"
		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"
		}
		PdfGenerator.GeneratePdf(options)
	End Sub
End Class
$vbLabelText   $csharpLabel

Dieses Beispiel veranschaulicht die Grundlagen der Integration von IronPDF mit C#-Generics, was eine flexible Möglichkeit bietet, PDFs aus HTML-Inhalten zu generieren, während anpassbare Metadaten oder Konfigurationen durch die generische PdfOptions-Klasse ermöglicht werden. Sie können dies erweitern, indem Sie anspruchsvollere Optionen und Renderer-Konfigurationen hinzufügen, die Sie für Ihre Anwendung benötigen.

C# Generics (Wie sie für Entwickler funktionieren): Abbildung 1 - Beispielcode-Ausgabe unter Verwendung von Generics zur Erstellung eines PDF-Dokuments aus einem HTML-String mit IronPDF

Schlussfolgerung

C# Generics (Wie es für Entwickler funktioniert): Abbildung 2 - IronPDF-Lizenzseite

C# Generics ist ein leistungsfähiges Werkzeug für die Entwicklung von hochwertigem, wiederverwendbarem und typsicherem Code. Durch das Verständnis und die Anwendung von generischen Klassen, Methoden, Schnittstellen und Delegaten können Sie Code schreiben, der anpassungsfähiger und leichter zu warten ist. Generics ermöglichen nicht nur die Wiederverwendung von Code über verschiedene Datentypen hinweg, sondern sorgen auch für eine Typüberprüfung während der Kompilierung, was Laufzeitfehler reduziert und die Codequalität insgesamt verbessert. IronPDF bietet eine kostenlose Testversion seiner PDF-Bibliothekstools, mit Kosten ab $749 an.

Chipego
Software-Ingenieur
Chipego hat eine natürliche Fähigkeit zum Zuhören, die ihm hilft, Kundenprobleme zu verstehen und intelligente Lösungen anzubieten. Er trat dem Iron Software-Team 2023 bei, nachdem er einen Bachelor of Science in Informationstechnologie erworben hatte. IronPDF und IronOCR sind die beiden Produkte, auf die sich Chipego konzentriert hat, aber sein Wissen über alle Produkte wächst täglich, da er neue Wege findet, Kunden zu unterstützen. Er genießt die Zusammenarbeit bei Iron Software, da Teammitglieder aus dem gesamten Unternehmen ihre unterschiedlichen Erfahrungen einbringen und so zu effektiven, innovativen Lösungen beitragen. Wenn Chipego nicht an seinem Schreibtisch sitzt, kann man ihn oft bei einem guten Buch oder beim Fußballspielen antreffen.
< PREVIOUS
C# String.Join (Wie es für Entwickler funktioniert)
NÄCHSTES >
C# Virtual Keyword (Wie es für Entwickler funktioniert)