AYUDA .NET

C# Struct vs Class (Cómo funciona para los desarrolladores)

En C#, tanto los structs como las clases sirven como bloques de construcción fundamentales para organizar y almacenar datos, pero tienen características distintas que los hacen adecuados para diferentes escenarios. Comprender las diferencias entre estructuras y clases en C# es crucial para tomar decisiones informadas al diseñar sus aplicaciones en C#.

En este artículo, exploraremos las distinciones clave entre structs y clases, discutiendo sus casos de uso, gestión de memoria e implicaciones de rendimiento. Además, discutiremos cómo usar estructuras y clases con IronPDF for C# para la creación de archivos PDF.

1. Visión general de estructuras y clases

1.1. Clases (tipos de referencia)

Tipos de referencia: Una clase en C# es un tipo de referencia que reside en el montón, lo que significa que cuando se crea una instancia de una clase, se almacena en la memoria una referencia al objeto.

Asignación en el Heap: Las instancias de clases se asignan memoria en la asignación de memoria del heap, proporcionando flexibilidad en el tamaño y permitiendo que los objetos se compartan entre diferentes partes del código.

Constructor por defecto: Las clases pueden tener un constructor por defecto, que se proporciona automáticamente si no se define uno explícitamente.

Herencia: Las clases admiten herencia, lo que permite la creación de clases derivadas con características compartidas.

using System;
// Define a class
public class MyClass
{
    // Fields (data members)
    public int MyField;
    // Constructor
    public MyClass(int value)
    {
        MyField = value;
    }
    // Method
    public void Display()
    {
        Console.WriteLine($"Value in MyClass: {MyField}");
    }
}
class Program
{
    static void Main()
    {
        // Create an instance of the class
        MyClass myClassInstance = new MyClass(10);
        // Access field and call method
        myClassInstance.Display();
        // Classes are reference types, so myClassInstance refers to the same object in memory
        MyClass anotherInstance = myClassInstance;
        anotherInstance.MyField = 20;
        // Both instances refer to the same object, so the change is reflected in both
        myClassInstance.Display();
        anotherInstance.Display();
    }
}
using System;
// Define a class
public class MyClass
{
    // Fields (data members)
    public int MyField;
    // Constructor
    public MyClass(int value)
    {
        MyField = value;
    }
    // Method
    public void Display()
    {
        Console.WriteLine($"Value in MyClass: {MyField}");
    }
}
class Program
{
    static void Main()
    {
        // Create an instance of the class
        MyClass myClassInstance = new MyClass(10);
        // Access field and call method
        myClassInstance.Display();
        // Classes are reference types, so myClassInstance refers to the same object in memory
        MyClass anotherInstance = myClassInstance;
        anotherInstance.MyField = 20;
        // Both instances refer to the same object, so the change is reflected in both
        myClassInstance.Display();
        anotherInstance.Display();
    }
}
Imports System
' Define a class
Public Class [MyClass]
	' Fields (data members)
	Public MyField As Integer
	' Constructor
	Public Sub New(ByVal value As Integer)
		MyField = value
	End Sub
	' Method
	Public Sub Display()
		Console.WriteLine($"Value in MyClass: {MyField}")
	End Sub
End Class
Friend Class Program
	Shared Sub Main()
		' Create an instance of the class
		Dim myClassInstance As [MyClass] = New [MyClass](10)
		' Access field and call method
		myClassInstance.Display()
		' Classes are reference types, so myClassInstance refers to the same object in memory
		Dim anotherInstance As [MyClass] = myClassInstance
		anotherInstance.MyField = 20
		' Both instances refer to the same object, so the change is reflected in both
		myClassInstance.Display()
		anotherInstance.Display()
	End Sub
End Class
$vbLabelText   $csharpLabel

C# Estructura vs Clase (Cómo funciona para los desarrolladores): Figura 1 - Salida en la consola del código anterior

1.2. Estructuras (tipos de valor)

Tipos de Valor: Los structs son tipos de valor, lo que significa que los datos reales se almacenan donde se declara la variable, en lugar de en una ubicación separada en la memoria como los tipos primitivos. Esto también significa que al struct no se le puede asignar un valor nulo como su tipo de valor sin convertirlo en un tipo anulable con la etiqueta Nullable<>.

Asignación en Pila: Las instancias de estructuras se asignan memoria en la pila, lo que conduce a una asignación y desasignación más rápidas, pero con limitaciones en tamaño y alcance.

No Default Constructor: Los structs no tienen un constructor por defecto a menos que se defina explícitamente uno. Cada campo debe ser inicializado durante la instanciación.

Sin herencia: Las estructuras no admiten herencia. Se utilizan principalmente para estructuras de datos ligeras.

using System;
// Define a struct
public struct MyStruct
{
    // Fields (data members)
    public int MyField;
    // Constructor
    public MyStruct(int value)
    {
        MyField = value;
    }
    // Method
    public void Display()
    {
        Console.WriteLine($"Value in MyStruct: {MyField}");
    }
}
class Program
{
    static void Main()
    {
        // Create an instance of the struct
        MyStruct myStructInstance = new MyStruct(10);
        // Access field and call method
        myStructInstance.Display();
        // Structs are value types, so myStructInstance is a copy
        MyStruct anotherInstance = myStructInstance;
        anotherInstance.MyField = 20;
        // Changes to anotherInstance do not affect myStructInstance
        myStructInstance.Display();
        anotherInstance.Display();
    }
}
using System;
// Define a struct
public struct MyStruct
{
    // Fields (data members)
    public int MyField;
    // Constructor
    public MyStruct(int value)
    {
        MyField = value;
    }
    // Method
    public void Display()
    {
        Console.WriteLine($"Value in MyStruct: {MyField}");
    }
}
class Program
{
    static void Main()
    {
        // Create an instance of the struct
        MyStruct myStructInstance = new MyStruct(10);
        // Access field and call method
        myStructInstance.Display();
        // Structs are value types, so myStructInstance is a copy
        MyStruct anotherInstance = myStructInstance;
        anotherInstance.MyField = 20;
        // Changes to anotherInstance do not affect myStructInstance
        myStructInstance.Display();
        anotherInstance.Display();
    }
}
Imports System
' Define a struct
Public Structure MyStruct
	' Fields (data members)
	Public MyField As Integer
	' Constructor
	Public Sub New(ByVal value As Integer)
		MyField = value
	End Sub
	' Method
	Public Sub Display()
		Console.WriteLine($"Value in MyStruct: {MyField}")
	End Sub
End Structure
Friend Class Program
	Shared Sub Main()
		' Create an instance of the struct
		Dim myStructInstance As New MyStruct(10)
		' Access field and call method
		myStructInstance.Display()
		' Structs are value types, so myStructInstance is a copy
		Dim anotherInstance As MyStruct = myStructInstance
		anotherInstance.MyField = 20
		' Changes to anotherInstance do not affect myStructInstance
		myStructInstance.Display()
		anotherInstance.Display()
	End Sub
End Class
$vbLabelText   $csharpLabel

Estructura vs Clase en C# (Cómo funciona para los desarrolladores): Figura 2 - Salida en la consola del código anterior

2. Casos de uso y directrices

2.1. Cuándo utilizar las clases

Estado y Comportamiento Complejos: Utiliza clases cuando necesites modelar estructuras de datos complejas con estado y comportamiento. Las clases son adecuadas para representar objetos complejos con múltiples propiedades y métodos.

Semántica de Referencia: Si quieres compartir instancias de objetos y que los cambios se reflejen en diferentes partes de tu código, las clases son la opción adecuada.

2.2. Cuándo utilizar estructuras

Estructuras de Datos Simples: Los structs son ideales para estructuras de datos más simples que representan entidades ligeras como estructuras de datos pequeñas, tales como puntos, rectángulos, pares clave-valor, o si el struct representa lógicamente un solo valor, similar a los tipos primitivos.

Semántica de Valor: Cuando prefieres la semántica de valor y deseas evitar la sobrecarga de la asignación en el heap, las estructuras son una buena opción.

Consideraciones de rendimiento: En escenarios donde el rendimiento es crítico, especialmente para objetos pequeños y de uso frecuente, las estructuras pueden ser más eficientes debido a la asignación en la pila.

3. Diferencias en la asignación de memoria

3.1. Clases

Conteo de Referencias: La memoria para las instancias de clase se gestiona a través del conteo de referencias por el recolector de basura. Los objetos son susceptibles de ser recogidos cuando ya no hay referencias a ellos.

Potencial de Fugas de Memoria: El manejo inadecuado de referencias puede llevar a fugas de memoria si los objetos no se eliminan correctamente cuando ya no se necesitan.

3.2. Estructuras

Sin recolección de basura: Los structs no dependen de la recolección de basura ya que son tipos de valor y se gestionan de manera diferente. Se desasignan automáticamente cuando salen del ámbito de aplicación.

Overhead de Memoria Limitado: Los structs tienen un overhead de memoria inferior en comparación con las clases, lo que los hace eficientes para escenarios donde el uso de la memoria es una preocupación.

4. 4. Consideraciones sobre el rendimiento

Clases

Acceso indirecto: Dado que las instancias de clase se acceden a través de referencias, hay un nivel adicional de indirecta, lo que puede introducir un ligero costo en el rendimiento.

Asignación en el montón: La asignación dinámica de memoria en el montón puede llevar a tiempos más largos de creación y destrucción de objetos.

Estructuras

Acceso Directo: Los structs se acceden directamente, eliminando la necesidad de un nivel adicional de indirección. Esto puede mejorar el rendimiento de los objetos pequeños de uso frecuente.

Asignación de pila: La asignación de memoria en la pila proporciona una creación y destrucción más rápida de instancias de estructuras.

5. Presentación de IronPDF

Descripción general de IronPDF: Biblioteca robusta de C# para manipulación de PDF está diseñada para la generación, manipulación y renderización de PDF de manera fluida dentro de aplicaciones .NET. Con IronPDF, los desarrolladores pueden crear, modificar e interactuar sin esfuerzo con documentos PDF, lo que la convierte en una herramienta esencial para tareas que van desde la generación dinámica de PDF a partir de contenido HTML hasta la extracción de datos de documentos existentes. Esta versátil biblioteca simplifica las funciones relacionadas con PDF, proporcionando un completo conjunto de características para los desarrolladores que trabajan en aplicaciones web, software de escritorio o cualquier proyecto .NET que requiera un manejo eficaz de PDF.

5.1. Instalación de IronPDF

Antes de sumergirse en los ejemplos de código, es necesario instalar IronPDF. Puede hacerlo utilizando la consola del gestor de paquetes NuGet o añadiendo una referencia a la biblioteca IronPDF en su proyecto. Los siguientes pasos describen el proceso de instalación:

  1. Consola del Administrador de Paquetes de NuGet:
    :ProductInstall
    :ProductInstall
SHELL
  1. Administrador de Paquetes UI: Busque "IronPDF" en el Administrador de Paquetes NuGet y instale la última versión.

    Una vez instalado IronPDF, estará listo para aprovechar sus funciones de gestión de archivos PDF en sus aplicaciones C#.

5.2. Uso de Struct y Class con IronPDF

using IronPdf;
using System;
// Sample class
class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}
// Sample struct
struct Point
{
    public int X { get; set; }
    public int Y { get; set; }
}
class Program
{
    static void Main()
    {
        // Sample instances of class and struct
        Person person = new Person { Name = "John Doe", Age = 30 };
        Point point = new Point { X = 10, Y = 20 };
        // Create a new PDF document
        var renderer = new ChromePdfRenderer();
        // Add content with information from class and struct
        string content = $@"<!DOCTYPE html>
                            <html>
                            <body>
                                <h1>Information in IronPDF</h1>
                                <p>Name: {person.Name}</p>
                                <p>Age: {person.Age}</p>
                                <p>Point X: {point.X}</p>
                                <p>Point Y: {point.Y}</p>
                            </body>
                            </html>";
        // Render HTML content to PDF
        var pdf = renderer.RenderHtmlAsPdf(content);
        // Save the PDF to a file
        pdf.SaveAs("InformationDocument.pdf");
    }
}
using IronPdf;
using System;
// Sample class
class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}
// Sample struct
struct Point
{
    public int X { get; set; }
    public int Y { get; set; }
}
class Program
{
    static void Main()
    {
        // Sample instances of class and struct
        Person person = new Person { Name = "John Doe", Age = 30 };
        Point point = new Point { X = 10, Y = 20 };
        // Create a new PDF document
        var renderer = new ChromePdfRenderer();
        // Add content with information from class and struct
        string content = $@"<!DOCTYPE html>
                            <html>
                            <body>
                                <h1>Information in IronPDF</h1>
                                <p>Name: {person.Name}</p>
                                <p>Age: {person.Age}</p>
                                <p>Point X: {point.X}</p>
                                <p>Point Y: {point.Y}</p>
                            </body>
                            </html>";
        // Render HTML content to PDF
        var pdf = renderer.RenderHtmlAsPdf(content);
        // Save the PDF to a file
        pdf.SaveAs("InformationDocument.pdf");
    }
}
Imports IronPdf
Imports System
' Sample class
Friend Class Person
	Public Property Name() As String
	Public Property Age() As Integer
End Class
' Sample struct
Friend Structure Point
	Public Property X() As Integer
	Public Property Y() As Integer
End Structure
Friend Class Program
	Shared Sub Main()
		' Sample instances of class and struct
		Dim person As New Person With {
			.Name = "John Doe",
			.Age = 30
		}
		Dim point As New Point With {
			.X = 10,
			.Y = 20
		}
		' Create a new PDF document
		Dim renderer = New ChromePdfRenderer()
		' Add content with information from class and struct
		Dim content As String = $"<!DOCTYPE html>
                            <html>
                            <body>
                                <h1>Information in IronPDF</h1>
                                <p>Name: {person.Name}</p>
                                <p>Age: {person.Age}</p>
                                <p>Point X: {point.X}</p>
                                <p>Point Y: {point.Y}</p>
                            </body>
                            </html>"
		' Render HTML content to PDF
		Dim pdf = renderer.RenderHtmlAsPdf(content)
		' Save the PDF to a file
		pdf.SaveAs("InformationDocument.pdf")
	End Sub
End Class
$vbLabelText   $csharpLabel
  • Persona es una clase de ejemplo que representa a una persona con propiedades de Nombre y Edad.
  • Punto es una estructura de muestra que representa un punto en un sistema de coordenadas 2D con propiedades X y Y.
  • Se crean instancias de la clase Person y la estructura Point.
  • A continuación, el contenido HTML se renderiza en el documento PDF, que se guarda como "DocumentoInformacion.pdf".

5.2.1. Archivo PDF de salida

C# Struct vs Class (Cómo Funciona Para Desarrolladores): Figura 3 - El archivo PDF generado del código anterior

6. Conclusión

En conclusión, la elección entre utilizar structs y clases de C# depende de los requisitos y características específicos de su aplicación. Las clases, al ser tipos de referencia, son adecuadas para modelar entidades complejas con estado y comportamiento, soportar la herencia y facilitar las instancias compartidas. Por otro lado, los structs, como tipos de valor, son ideales para estructuras de datos ligeras con semántica de valor, ofreciendo ventajas de rendimiento en términos de asignación de pila y acceso directo.

IronPDF ofrece una Licencia de Prueba Gratuita para Evaluación para los usuarios, lo cual es una buena oportunidad para conocer las características y funcionalidades de IronPDF. Para obtener más información sobre IronPDF, visite la Documentación Integral de IronPDF y un tutorial detallado para crear archivos PDF utilizando IronPDF está disponible en el Tutorial de Generación de PDF de IronPDF.

Chipego
Ingeniero de software
Chipego tiene una habilidad natural para escuchar que le ayuda a comprender los problemas de los clientes y a ofrecer soluciones inteligentes. Se unió al equipo de Iron Software en 2023, después de estudiar una licenciatura en Tecnología de la Información. IronPDF e IronOCR son los dos productos en los que Chipego se ha centrado, pero su conocimiento de todos los productos crece día a día, a medida que encuentra nuevas formas de ayudar a los clientes. Disfruta de lo colaborativa que es la vida en Iron Software, con miembros del equipo de toda la empresa que aportan su variada experiencia para contribuir a soluciones eficaces e innovadoras. Cuando Chipego está lejos de su escritorio, a menudo se le puede encontrar disfrutando de un buen libro o jugando al fútbol.
< ANTERIOR
C# Initialize Array (Cómo Funciona Para Desarrolladores)
SIGUIENTE >
NPlot C# (Cómo funciona para desarrolladores)