# Declarando una estructura
public struct Vector
{
public int X;
public int Y;
public int Z;
}
public struct Point
{
public decimal x, y;
public Point(decimal pointX, decimal pointY)
{
x = pointX;
y = pointY;
}
}
Vector v1 = null; //illegal
Vector? v2 = null; //OK
Nullable<Vector> v3 = null // OK
//Both of these are acceptable
Vector v1 = new Vector();
v1.X = 1;
v1.Y = 2;
v1.Z = 3;
Vector v2;
v2.X = 1;
v2.Y = 2;
v2.Z = 3;
Sin embargo, el new
se debe usar el operador para usar un inicializador:
Vector v1 = new MyStruct { X=1, Y=2, Z=3 }; // OK
Vector v2 { X=1, Y=2, Z=3 }; // illegal
Una estructura puede declarar todo lo que puede declarar una clase, con algunas excepciones:
- Una estructura no puede declarar un constructor sin parámetros.
struct
los campos de instancia se pueden configurar a través de un constructor parametrizado o individualmente después destruct
construcción. Los miembros privados solo pueden ser inicializados por el constructor. - Una estructura no puede declarar miembros como protegidos, ya que está sellada implícitamente.
- Los campos de estructura solo se pueden inicializar si son constantes o estáticos.
# Uso de estructura
Con constructor:
Vector v1 = new Vector();
v1.X = 1;
v1.Y = 2;
v1.Z = 3;
Console.WriteLine("X = {0}, Y = {1}, Z = {2}",v1.X,v1.Y,v1.Z);
// Output X=1,Y=2,Z=3
Vector v1 = new Vector();
//v1.X is not assigned
v1.Y = 2;
v1.Z = 3;
Console.WriteLine("X = {0}, Y = {1}, Z = {2}",v1.X,v1.Y,v1.Z);
// Output X=0,Y=2,Z=3
Point point1 = new Point();
point1.x = 0.5;
point1.y = 0.6;
Point point2 = new Point(0.5, 0.6);
Sin constructor:
Vector v1;
v1.Y = 2;
v1.Z = 3;
Console.WriteLine("X = {0}, Y = {1}, Z = {2}",v1.X,v1.Y,v1.Z);
//Output ERROR "Use of possibly unassigned field 'X'
Vector v1;
v1.X = 1;
v1.Y = 2;
v1.Z = 3;
Console.WriteLine("X = {0}, Y = {1}, Z = {2}",v1.X,v1.Y,v1.Z);
// Output X=1,Y=2,Z=3
Point point3;
point3.x = 0.5;
point3.y = 0.6;
Si usamos una estructura con su constructor, no vamos a tener problemas con el campo sin asignar (cada campo sin asignar tiene un valor nulo).
A diferencia de las clases, no es necesario construir una estructura, es decir, no es necesario usar la nueva palabra clave, a menos que necesite llamar a uno de los constructores. Una estructura no requiere la nueva palabra clave porque es un tipo de valor y, por lo tanto, no puede ser nula.
# Interfaz de implementación de Struct
public interface IShape
{
decimal Area();
}
public struct Rectangle : IShape
{
public decimal Length { get; set; }
public decimal Width { get; set; }
public decimal Area()
{
return Length * Width;
}
}
# Las estructuras se copian en la asignación
Dado que las estructuras son tipos de valor, todos los datos se copian en la asignación, y cualquier modificación a la nueva copia no cambia los datos de la copia original. El fragmento de código siguiente muestra que p1
es copiado a p2
y cambios realizados en p1
no afecta a p2
instancia.
var p1 = new Point {
x = 1,
y = 2
};
Console.WriteLine($"{p1.x} {p1.y}"); // 1 2
var p2 = p1;
Console.WriteLine($"{p2.x} {p2.y}"); // Same output: 1 2
p1.x = 3;
Console.WriteLine($"{p1.x} {p1.y}"); // 3 2
Console.WriteLine($"{p2.x} {p2.y}"); // p2 remain the same: 1 2
# Comentarios
A diferencia de las clases, un struct
es un tipo de valor y se crea en la pila local y no en el montón administrado, de forma predeterminada . Esto significa que una vez que la pila específica queda fuera del alcance, el struct
está desasignado. Tipos de referencia contenidos de struct
desasignados Los correos electrónicos también se barren, una vez que el GC determina que el struct
ya no hace referencia a ellos. .
struct
Los correos electrónicos no pueden heredar y no pueden ser bases para la herencia, están implícitamente sellados y tampoco pueden incluir protected
miembros Sin embargo, un struct
puede implementar una interfaz, como lo hacen las clases.