¿Cuándo debería usar una estructura en lugar de una clase?
MSDN dice que debes usar estructuras cuando necesites objetos livianos. ¿Existen otros escenarios en los que una estructura es preferible a una clase?
Algunas personas tal vez hayan olvidado que:
- Las estructuras pueden tener métodos.
- Las estructuras no se pueden heredar.
Entiendo las diferencias técnicas entre estructuras y clases, simplemente no tengo una buena idea de cuándo usar una estructura.
MSDN tiene la respuesta: Elegir entre clases y estructuras .
Básicamente, esa página le brinda una lista de verificación de 4 elementos y le dice que use una clase a menos que su tipo cumpla con todos los criterios.
No defina una estructura a menos que el tipo tenga todas las características siguientes:
- Lógicamente representa un valor único, similar a los tipos primitivos (entero, doble, etc.).
- Tiene un tamaño de instancia inferior a 16 bytes.
- Es inmutable.
- No será necesario encajonarlo con frecuencia.
Me sorprende no haber leído ninguna de las respuestas anteriores, que considero el aspecto más crucial:
Utilizo estructuras cuando quiero un tipo sin identidad. Por ejemplo un punto 3D:
public struct ThreeDimensionalPoint
{
public readonly int X, Y, Z;
public ThreeDimensionalPoint(int x, int y, int z)
{
this.X = x;
this.Y = y;
this.Z = z;
}
public override string ToString()
{
return "(X=" + this.X + ", Y=" + this.Y + ", Z=" + this.Z + ")";
}
public override int GetHashCode()
{
return (this.X + 2) ^ (this.Y + 2) ^ (this.Z + 2);
}
public override bool Equals(object obj)
{
if (!(obj is ThreeDimensionalPoint))
return false;
ThreeDimensionalPoint other = (ThreeDimensionalPoint)obj;
return this == other;
}
public static bool operator ==(ThreeDimensionalPoint p1, ThreeDimensionalPoint p2)
{
return p1.X == p2.X && p1.Y == p2.Y && p1.Z == p2.Z;
}
public static bool operator !=(ThreeDimensionalPoint p1, ThreeDimensionalPoint p2)
{
return !(p1 == p2);
}
}
Si tiene dos instancias de esta estructura, no le importa si son uno o dos datos en la memoria. Sólo te importa el valor que tienen.
Bill Wagner tiene un capítulo sobre esto en su libro "efectivo c#" ( http://www.amazon.com/Effective-Specific-Ways-Improve-Your/dp/0321245660 ). Concluye utilizando el siguiente principio:
- ¿Es la responsabilidad principal del tipo de almacenamiento de datos?
- ¿Su interfaz pública está definida completamente por propiedades que acceden o modifican sus miembros de datos?
- ¿Estás seguro de que tu tipo nunca tendrá subclases?
- ¿Estás seguro de que tu tipo nunca será tratado polimórficamente?
Si responde "sí" a las 4 preguntas: utilice una estructura. De lo contrario, utilice una clase.