Structs en C# – Diferencias con las clases
Aprende las diferencias entre structs y clases en C#, incluyendo modelo de memoria, herencia y rendimiento.
En C#, class (clase) y struct (estructura) son dos tipos fundamentales que combinan datos y comportamientos.
Aunque a primera vista puedan parecer similares, difieren de manera significativa en la gestión de memoria y en sus propósitos de uso.
Los tipos class se comportan como tipos de referencia, mientras que los tipos struct son tipos de valor.
¿Qué es un Struct?
Un struct se utiliza normalmente para representar conjuntos de datos pequeños, simples y de corta duración.
Es adecuado, por ejemplo, para un punto de coordenadas 2D o un intervalo de fechas.
Por defecto es un tipo de valor, lo que significa que al copiarlo se crea una nueva copia independiente.
public struct Point
{
public int X { get; set; }
public int Y { get; set; }
public Point(int x, int y)
{
X = x;
Y = y;
}
public void Print()
{
Console.WriteLine($"({X}, {Y})");
}
}
Diferencias entre Struct y Class
A continuación, se enumeran las diferencias más importantes entre struct y class:
- Categoría de tipo:
structes un tipo de valor,classes un tipo de referencia. - Memoria: Las estructuras suelen almacenarse en la pila (stack); las clases en el heap.
- Copia: Al asignar una estructura, se copian todos los valores. En las clases, solo se copia la referencia.
- Constructor sin parámetros: Antes de C# 10, las estructuras no podían definir un constructor sin parámetros, mientras que las clases sí.
- Herencia: Las estructuras no pueden heredar de otra estructura o clase, pero pueden implementar
interfaces. - Valores nulos: Las estructuras no son nulas por defecto; se permiten estructuras anulables (
Point?). Las clases sí pueden ser nulas.
Comportamiento de Copia
Cuando se copian estructuras, se crea una copia completamente nueva. En las clases, solo se copia la referencia y ambas variables apuntan al mismo objeto.
Point p1 = new Point(10, 20);
Point p2 = p1; // copiado
p2.X = 99;
Console.WriteLine(p1.X); // 10 (copia independiente)
Console.WriteLine(p2.X); // 99
class Person
{
public string Name { get; set; }
}
var p1 = new Person { Name = "John" };
var p2 = p1; // misma referencia
p2.Name = "Michael";
Console.WriteLine(p1.Name); // "Michael"
Console.WriteLine(p2.Name); // "Michael"
Tipos de Referencia y Tipos de Valor
En C#, los tipos se dividen en dos grandes categorías: tipos de valor y tipos de referencia.
Un struct es un tipo de valor; al asignarlo a una variable o pasarlo como parámetro a un método, se copian todos los datos.
Por lo tanto, los cambios en una copia no afectan a la otra.
Una class es un tipo de referencia; al asignarla a una variable, se copia una referencia que apunta al mismo objeto en memoria.
Por eso, un cambio a través de una referencia se refleja en las demás.
// Tipo de valor (struct)
Point p1 = new Point(1, 2);
Point p2 = p1; // copia
p2.X = 99;
Console.WriteLine(p1.X); // 1
Console.WriteLine(p2.X); // 99
// Tipo de referencia (class)
Person a = new Person { Name = "Alice" };
Person b = a; // mismo objeto
b.Name = "Maria";
Console.WriteLine(a.Name); // Maria
Console.WriteLine(b.Name); // Maria
¿Cuándo usar Struct y cuándo usar Class?
Use struct para tipos de datos pequeños, inmutables (o casi inmutables) y con un comportamiento limitado.
Prefiera class para objetos grandes, complejos, de ciclo de vida largo y que requieran herencia.
Por ejemplo: puntos 3D, valores de color, intervalos de fechas → struct;
cliente, producto, pedido → class.
Ejemplo: Cálculo con Struct
public struct Point2D
{
public int X { get; }
public int Y { get; }
public Point2D(int x, int y)
{
X = x;
Y = y;
}
public double DistanceTo(Point2D other)
{
int dx = X - other.X;
int dy = Y - other.Y;
return Math.Sqrt(dx * dx + dy * dy);
}
}
class Program
{
static void Main()
{
var p1 = new Point2D(0, 0);
var p2 = new Point2D(3, 4);
Console.WriteLine(p1.DistanceTo(p2)); // 5
}
}
TL;DR
struct= tipo de valor,class= tipo de referencia.- Struct es adecuado para conjuntos de datos pequeños y simples; Class para objetos complejos.
- Copiar un struct crea una copia independiente; copiar una clase copia una referencia al mismo objeto.
- Struct no puede heredar pero puede implementar interfaces; Class puede heredar.
- Struct no es nulo por defecto; Class puede ser nulo.