Pruebas en un entorno real
Pruebe en producción sin marcas de agua.
Funciona donde lo necesites.
Los genéricos de C# introducen una forma de diseñar clases, métodos, interfaces y delegados en los que el tipo de datos que gestionan puede especificarse como parámetro. Este concepto, conocido como parámetro de tipo genérico, permite crear componentes de código flexibles y reutilizables. Utilizando genéricospuede maximizar la reutilización del código, la seguridad de tipos y el rendimiento. Por ejemplo, una clase genérica puede definirse una vez pero instanciarse con varios tipos de datos, lo que ofrece versatilidad e integridad de tipos. En este artículo, aprenderemos los conceptos básicos de C# Generics y Biblioteca IronPDF.
Una clase genérica en C# es un plano para crear una clase con un marcador de posición para el tipo que contiene o sobre el que opera. Este marcador de posición, a menudo denotado por T, representa un parámetro de tipo que se especifica cuando se instancia la clase. Podemos crear clases genéricas con el parámetro de tipo T para manejar varios tipos de datos. Las clases genéricas son particularmente útiles para las clases de colección, como listas, colas y tablas hash, ya que pueden contener cualquier tipo de datos al tiempo que garantizan la seguridad de tipo y reducen la necesidad de casting.
Considere una clase genérica llamada Caja que está diseñada para almacenar un valor de cualquier tipo:
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
Para utilizar esta clase, se crea una instancia especificando el tipo real para 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")
Este código ilustra cómo una sola clase (Caja
Los métodos genéricos son similares a las clases genéricas, pero se definen con parámetros de tipo a nivel de método. Esto permite crear métodos que pueden operar sobre diferentes tipos estando definidos en una clase no genérica o en una genérica.
He aquí un método que intercambia dos elementos en un array de cualquier tipo:
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
El uso del método anterior puede ser el siguiente:
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)
Las interfaces genéricas y los delegados permiten definir contratos y métodos de devolución de llamada que pueden operar con cualquier tipo. Implementar una interfaz genérica o utilizar un delegado genérico en su clase o método mejora la flexibilidad y la reutilización del código.
Una interfaz genérica de repositorio para operaciones de acceso a datos podría tener este aspecto:
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
Esta interfaz puede ser implementada por cualquier clase para manejar tipos de datos específicos, permitiendo patrones de acceso a datos consistentes a través de diferentes tipos.
Se puede utilizar un delegado genérico para definir una llamada de retorno segura:
public delegate void Action<T>(T item);
public delegate void Action<T>(T item);
Public Delegate Sub Action(Of T)(ByVal item As T)
Clases genéricas de colección, como List
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")
Además de utilizar los tipos genéricos incorporados, puede crear los suyos propios para encapsular operaciones comunes a distintos tipos de datos, pero que deben gestionarse de forma específica para cada tipo. Este enfoque es especialmente útil para crear bibliotecas, marcos de trabajo o utilidades que vayan a utilizarse con distintos tipos de datos.
Considere una clase genérica Resultado que encapsula los resultados de la operación junto con una bandera de éxito y un mensaje opcional:
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
IronPDF es una completa biblioteca diseñada para que los desarrolladores .NET puedan crear, editar y extraer documentos PDF dentro de sus aplicaciones. IronPDF ayuda en generar PDF a partir de HTMLedición de PDF existentes, conversión de PDF a imágenes y mucho más. Aunque IronPDF en sí no se basa en genéricos, entender cómo interactuar con esta biblioteca en un entorno C# puede mejorar enormemente las capacidades de gestión de documentos de su aplicación.
La idea de utilizar genéricos aquí es crear un método reutilizable que pueda generar un PDF a partir de cualquier cadena HTML dada. Este método será genérico, permitiéndonos especificar diferentes tipos de metadatos o configuraciones según sea necesario.
En primer lugar, vamos a definir una clase genérica simple que contendrá nuestras opciones de generación de PDF. A efectos de demostración, esta clase será básica, pero puede ampliarla con más propiedades para adaptarla a sus necesidades.
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
Ahora, vamos a crear un método estático que genere un PDF utilizando IronPDF, aprovechando nuestro PdfOptions
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
Por último, vamos a utilizar nuestra clase PdfGenerator para generar un documento PDF. En este ejemplo, la propiedad Metadatos podría ser una cadena que contenga un título o cualquier otra información que considere relevante.
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
Este ejemplo ilustra los fundamentos de la integración de IronPDF con C# Generics, proporcionando una forma flexible de generar PDFs a partir de contenido HTML al tiempo que permite metadatos personalizables o configuraciones a través del genérico PdfOptions
Los genéricos de C# son una potente herramienta para desarrollar código de alta calidad, reutilizable y seguro desde el punto de vista tipográfico. Al comprender y aplicar clases, métodos, interfaces y delegados genéricos, puede escribir código más adaptable y fácil de mantener. Los genéricos no sólo permiten la reutilización del código en distintos tipos de datos, sino que también garantizan la comprobación de tipos en tiempo de compilación, lo que reduce los errores en tiempo de ejecución y mejora la calidad general del código. IronPDF ofrece un prueba gratuita cuesta $749 en adelante.
9 productos API .NET para sus documentos de oficina