Botón para abrir el Menú Botón para cerrar el Menú
Logo da empresa Alura
Iniciar Sesión Nuestros Planes
Formaciones Conoce a Luri
  • Programación _
  • Front End _
  • Data Science _
  • DevOps _
  • Innovación y Gestión _
Artículos de Tecnología > Programación

C#: entender clases y structs

André Bessa
André Bessa
19/09/2023

Compartir

Mira este artículo:
  1. ¿Qué son las clases?
  2. Pero, ¿qué son las Structs?
  3. ¿Usar clases o struct?
  4. Conclusión

capa - Descripción de la imagen: Ilustración con dos personas con las letras VS encima de ellas, representando un combate entre ellas.

Cuando profundizamos en el aprendizaje de un lenguaje de programación, muchas veces nos encontramos con algunas características muy singulares, propias de un lenguaje en concreto y otras comunes a varios lenguajes, como, por ejemplo, los tipos de estructuras de datos disponibles. En los lenguajes orientados a objetos se utiliza más la estructura sin dudas sobre las clases.

Pero, ¿será siempre la mejor estructura a crear una clase? ¿Cuál es el costo computacional en usar de una clase en comparación con un tipo de valor?

En C#, al igual que en el lenguaje C, hay un tipo de estructura que incluso es muy utilizada por el propio framework .NET, pero no tiene todo el “glamour” de las clases. Hablamos de structs (o estructuras), que pueden ser de gran ayuda para crear códigos que funcionen con pequeños conjuntos de datos.

Pero, ¿cómo creamos una struct? ¿En qué situaciones debo usarlos? Y la clásica pregunta: ¿usar clases o estructuras? En el siguiente texto responderemos algunas de estas preguntas.

¿Qué son las clases?

Las diversas literaturas técnicas disponibles definen la clase como un molde para crear objetos. Una definición muy interesante es la de Everton Araújo, autor del libro "Orientación a objetos en C#" de la editora “Casa do Código”. Según Araújo, una clase "es un conjunto o grupo de objetos que comparten propiedades y métodos en común".

Pero este concepto de clases y objetos nos lleva al paradigma de programación de la orientación a objetos, que es una forma de pensar y programar software teniendo en cuenta aspectos de nuestra realidad, como un automóvil, una persona o incluso conceptos más abstractos como una cuenta bancaria.

Entonces, con base en estas definiciones, imagina que estás leyendo un libro en particular, para ser más exactos, el libro de Everton Araújo. ¿Este libro es un objeto, verdad? ¿Cuántas páginas tiene este libro? Todo libro tiene algunas características como título, editora, autor, número de páginas, entre otras. Podemos ir más allá y aplicar estas características a otros objetos que se clasifican como libros, ¿verdad? Si es así, podemos crear una clase que contenga estas características. En C#, podemos definir una clase de la siguiente manera:

public class Libro 
{ 
    public string Titulo { get; set; } 
    public string Autor { get; set; } 
    public int NumeroPaginas { get; set; } 
    public bool TieneISBN { get; set; } 
    public string ISBN { get; set; } 
    public DateTime AnoPublicacion { get; set; } 
    
    public string DatosLibro() { 
        return $"Título: {this.Titulo}"+ 
        $"Autor: {this.Autor}"; 
	} 
}

Para utilizar objetos de una clase específica, necesitamos crear objetos de esa clase. Estas estructuras recibirán los valores de las propiedades para representar un "objeto" que existe en el mundo real. Un ejemplo de código:

Libro libro = new Libro() 
{ 
    Titulo = "Orientación a objetos en C#", 
    Autor = "Everton Araújo", 
    NumeroPaginas = 236, 
    AnoPublicacao = 2020, 
    TieneISBN = true, 
    ISBN = "978-65-86110-00-5" 
};

¡Excelente! Pero, ¿existe otra forma de representar una estructura de datos además de una clase? ¡Sí! C# tiene lo que se llama structs, que en determinadas situaciones se pueden utilizar en lugar de clases.

Pero, ¿qué son las Structs?

Las structs, muy comunes en el lenguaje C, tienen como objetivo estructurar algunos datos comunes dentro de un mismo contexto, algo muy similar a la idea de clases. En C#, una struct es similar a una clase, pero se define como un tipo de valor, mientras que una clase es un tipo de referencia.

Veamos un ejemplo de cómo se define una estructura:

public struct Persona 
{ 
    public int Edad { get; set; } 
    public string Nombre { get; set; } 
    public string Dni { get; set; } 
    public string correoElectronico { get; set; }
    public override string ToString() 
    { 
        return $"Nombre: {this.Nombre}" + 
        $"Correo Electrónico”: {this.correoElectronico}";
    }
}

Una struct es muy útil para situaciones donde necesitamos pocas variables, ya que los objetos creados a partir de estructuras son más livianos y al ser de tipo valor no funcionan con referencias.

Una struct puede tener constructores, campos, propiedades, métodos e indexadores. Además, una struct puede implementar una interfaz, aunque no existe herencia entre structs. Para utilizar un objeto creado a partir de una estructura, podemos hacer:

Persona persona = new(); 
persona.Dni = "12345678A"; 
persona.Nombre = "André Silva"; 
persona.correoElectronico = "[email protected]"; 
persona.Edad = 36;

Es decir, de la misma manera en que creamos una clase.

Resumiendo las características de las estructuras (structs):

  • Es un tipo de valor.
  • Cuando se define un constructor, debe tener parámetros.
  • No es posible inicializar un campo excepto a través de su constructor.
  • Una struct no puede ser la base de otra struct o clase.

¿Usar clases o struct?

Pero, ¿cuándo usar una clase o una struct? Una struct tiene una sintaxis y una definición similares a las de una clase, con algunas limitaciones, pero aún así es fácil de entender e implementar. Para responder si debemos usar clases o structs, volveremos a hablar sobre tipos de valor (value-type) y por referencia (reference-type).

En general, el compilador trabaja con dos áreas principales en la memoria para la manipulación de datos: la pila (stack) y el montón (heap). Observa en la siguiente imagen una abstracción:

Descripción de la imagen: Un bloque pequeño llamado `stack` y Un bloque mayor escrito `heap`.

El área que define la stack es mucho más pequeña en comparación con el área del heap, y ambas funcionan como una abstracción de una pila (el último en entrar es el primero en salir), pero cada uno con un tipo de diferente acceso.

Cuando creamos los tipos de datos más livianos, como los "tipos primitivos" y las estructuras (structs), estos se almacenan directamente en la stack, ya que son tipos que consumen poco espacio en la memoria. El stack tiene un rendimiento mucho mejor en la búsqueda de datos en su interior debido a que tiene un espacio menor. Por ejemplo:

Descripción de la imagen: Un bloque pequeño llamado “stack” con bloque interno con esta información: edad: int = 28.

En la imagen, nota que la declaración de la variable edad está junto a su valor, de ahí la definición de tipo de valor (value-type), y el acceso al compilador es muy rápido. Para los tipos más complejos como clases, objetos (objects), interfaces, delegates y cadenas (strings), estos se almacenan en el heap, como se muestra en la siguiente imagen:

Descripción de la imagen: Un bloque pequeño llamado “stack” con bloque interno con esta información: edad: int = 28. Un bloque mayor escrito “heap” con un bloque interno con esta información, respectivamente: miLibro: Libro.

Sin embargo, el compilador no accede directamente al heap. ¿Por qué? La respuesta es: ¡porque es un área muy grande! Y en el caso de buscar un objeto del tipo Libro, podría llevar bastante tiempo optimizando el acceso al heap, porque el procesador hace uso de la stack (que es más rápida y pequeña) para realizar esta operación. El compilador crea una referencia en la stack que apunta a la memoria del heap donde se encuentra el objeto.

Descripción de la imagen: Un bloque pequeño llamado “stack” con bloques internos con esta información por cada bloque, respectivamente: miLibro*: Libro y Edad: int = 28. Un bloque mayor escrito “heap” con un bloque interno con esta información, respectivamente: miLibro: Libro. Los bloques internos correspondientes del bloque pequeño y del bloque grande se conectan.

Este espacio en la memoria de la stack que señala una posición en el heap es lo que definimos como un puntero, y en la imagen usamos la notación de un asterisco para identificarlo. En resumen, declaramos un puntero en la stack que guarda una referencia a una posición en el heap, de ahí la definición de tipo de referencia (reference-type).

Los tipos de referencia se construyen utilizando la palabra reservada new, que indica que se debe reservar un espacio en la memoria del heap para un objeto específico.

Recuerda que las structs son tipos de valor, es decir, se almacenan en la stack, y aunque esta es más rápida, tiene un espacio mucho menor en comparación con el heap. Por lo tanto, las structs son recomendadas cuando necesitamos un conjunto de datos más pequeño.

Por ejemplo, en el código presentado para la struct Persona, si fuera necesario una gran cantidad de propiedades y campos, y la creación de varios objetos del tipo Persona, sería más interesante crearla como una clase para evitar el desbordamiento de la memoria de la stack. En la siguiente imagen, se muestra la representación de la struct Persona en la stack.

Descripción de la imagen: Un bloque pequeño llamado “stack” con bloques internos con esta información por cada bloque, respectivamente: `<<struct class=>` persona: Persona, Edad: int = 28, Nombre*: string, Dni*: string y correoElectronico*: string. Un bloque mayor escrito “heap” con bloques internos con estas informaciones, respectivamente: Nombre: string = “André Silva”, Dni: string = “12345678A” y correoElectronico: string = “[email protected]”. Los bloques internos correspondientes del bloque pequeño y del bloque grande se conectan.">

Es importante recordar que la biblioteca de clases .NET también utiliza estructuras (structs) para definir una serie de tipos y funcionalidades. Por ejemplo, tipos como int, float o bool son structs que heredan de una clase base object.

Descripción de la imagen: En la imagen se muestra un fragmento del editor de código Visual Studio Community que indica que el tipo int es una estructura (struct) del tipo readonly.

Otro ejemplo es la struct DateTime, que nos permite trabajar con la fecha y hora del sistema en nuestras aplicaciones. Es bastante interesante, ¿verdad?

Conclusión

En este artículo, hemos repasado brevemente la definición de clases en programación orientada a objetos, así como los tipos de valor y tipos de referencia, para comprender qué son lasstructs, cómo definirlas y en qué se diferencian de las clases.

Utilizar structs de manera adecuada en nuestros proyectos puede marcar la diferencia al brindar un mayor rendimiento. Es importante comprender que no toda estructura un poco más compleja necesita ser definida en una clase. ¿Te gustó? ¡Vamos a programar! 😉

Para más información sobre clases y estructuras (structs), consulte:

  • POO: ¿Qué es la programación orientada a objetos? | Alura Cursos Online
  • Formación C# y Orientación a Objetos | Alura Latam - Cursos online de tecnologia (aluracursos.com)
  • Structs - C# language specification | Microsoft Learn

foto-autor

André Bessa

Soy programador e instructor de programación usando C# y .NET. Licenciado en Sistemas de Información. Ya he programado usando Java, PHP, C#, PostgreSQL y MySQL, además de haber trabajado con soporte también. Siempre buscando aprender más sobre tecnologías, mis aficiones son los cómics y las series.

Este artículo fue traducido para Alura Latam por Brenda Souza.

Artículo Anterior
IntelliJ IDEA: consejos y trucos para usar en la vida cotidiana
Siguiente Artículo
Ordenando colecciones con Comparable y Comparator

Ver otros artículos sobre Programación

Navegación

  • Planes
  • Instructores
  • Blog
  • Política de privacidad
  • Términos de uso
  • Sobre nosotros
  • Preguntas frecuentes

¡CONTÁCTANOS!

  • ¡Quiero entrar en contacto!

Blog

  • Programación
  • Data Science
  • Front End
  • Innovación y Gestión
  • DevOps

AOVS Sistemas de Informática S.A CNPJ 05.555.382/0001-33

SÍGUENOS EN NUESTRAS REDES SOCIALES

YouTube Facebook Instagram Linkedin Whatsapp Spotify

NOVEDADES Y LANZAMIENTOS

Aliados

  • Programa de aceleração Scale-Up Endeavor
  • En Alura somos unas de las Scale-Ups seleccionadas por Endeavor, programa de aceleración de las empresas que más crecen en el país.
  • Growth Academy 2021 do Google For Startups
  • Fuimos unas de las 7 startups seleccionadas por Google For Startups en participar del programa Growth Academy en 2021
Alura

Powered by

Caelum

AOVS Sistemas de Informática S.A CNPJ 05.555.382/0001-33

SÍGUENOS EN NUESTRAS REDES SOCIALES

YouTube Facebook Instagram Linkedin Whatsapp Spotify

Cursos

Cursos de Programación
Lógica de Programación | Java
Cursos de Front End
HTML y CSS | JavaScript | React
Cursos de Data Science
Data Science | Machine Learning | Excel | Base de Datos | Data Visualization | Estadística
Cursos de DevOps
Docker | Linux
Cursos de Innovación y Gestión
Transformación Ágil | Marketing Analytics

Alura

  • Educação em Tecnologia

    • logo fiap FIAP
    • logo casa do codigo Casa do Código
    • logo pm3 PM3 - Cursos de Produto
  • Mais Alura

    • logo alura start START BY Alura
    • logo alura lingua Alura Língua
    • logo alura para empresas Alura Para Empresas
    • logo alura latam Alura LATAM
  • Comunidade

    • logo tech guide Tech Guide
    • logo 7 days of code 7 days of code
    • logo Hipsters ponto Jobs Hipsters ponto Jobs
  • Podcasts

    • logo Hipster Network Hipster Network
    • logo Hipsters ponto Tech Hipsters ponto Tech
    • logo Dev sem fronteiras Dev sem Fronteiras
    • logo Like a Boss Like a Boss
    • logo IA Sob Controle IA Sob Controle
    • logo Mesa de Produto Mesa de Produto
    • logo Decode Decode
    • logo FIAPCast FIAPCast