C# de los fundamentos al dominio — Lección 3
Comprensión de clases, estructuras, registros y seguridad nula.
Los artículos escritos en este blog fueron creados con el objetivo de enseñar. Además, la información del artículo puede ser incorrecta, así que tenga cuidado.
En C#, los datos se pueden expresar como clase, estructura y registro. Incluso si la gramática es similar, el método de copia y el significado de identidad son diferentes, por lo que se debe seleccionar de acuerdo con el propósito.
la clase es un tipo de referencia
public sealed class Player
{
public string Name { get; }
public int Health { get; private set; }
public Player(string name, int health)
{
Name = name;
Health = health;
}
}
Player first = new("Rose", 100);
Player second = first;
En el segundo, se copian las referencias que apuntan al mismo objeto, no el objeto completo. Si cambia Salud en un lado, podrá ver los resultados modificados en el otro lado.
estructura es un tipo de valor
public readonly struct Position
{
public float X { get; }
public float Y { get; }
public Position(float x, float y)
{
X = x;
Y = y;
}
}
Cuando asigna una estructura, el valor se copia. Es adecuado para datos pequeños y tratados como un valor único, como coordenadas o colores.
Las estructuras grandes tienen costos de copia más altos y las estructuras mutables pueden producir un comportamiento impredecible. Una estructura no es necesariamente rápida.
registro compara los valores mismos
public sealed record ItemKey(int Id, string Grade);
var a = new ItemKey(10, "Rare");
var b = new ItemKey(10, "Rare");
Console.WriteLine(a == b); // True
Las clases generales básicamente comparan si las referencias son las mismas, pero el registro compara si los valores de configuración son los mismos. Es bueno para usar con datos inmutables como configuraciones, comandos y mensajes de red.
Marcar el tipo como anulable
Player? FindPlayer(int id)
{
return players.TryGetValue(id, out Player? player)
? player
: null;
}
Player? target = FindPlayer(10);
if (target is not null)
{
Console.WriteLine(target.Name);
}
Al utilizar un tipo de referencia que acepta valores NULL, puede distinguir entre referencias que aceptan valores NULL y que no aceptan NULL. Antes de borrar la advertencia con !, debe verificar el flujo nuevamente para ver si nulo es realmente imposible.
La elección de clase, estructura y registro no es una cuestión de preferencia. Primero debe decidir si la identidad del objeto es importante, si la copia de valores es natural o si se trata de datos inmutables.