StructsStructs

Como classes, os structs são estruturas de dados que podem conter membros de dados e os membros da função, mas, ao contrário das classes, as estruturas são tipos de valor e não precisam de alocação de heap.Like classes, structs are data structures that can contain data members and function members, but unlike classes, structs are value types and do not require heap allocation. Uma variável de um tipo struct armazena diretamente os dados do struct, enquanto que uma variável de um tipo de classe armazena uma referência a um objeto alocado dinamicamente.A variable of a struct type directly stores the data of the struct, whereas a variable of a class type stores a reference to a dynamically allocated object. Os tipos de struct não dão suporte à herança especificada pelo usuário, e todos os tipos de structs são herdados implicitamente do tipo ValueType, que, por sua vez, é herdado implicitamente de object.Struct types do not support user-specified inheritance, and all struct types implicitly inherit from type ValueType, which in turn implicitly inherits from object.

Os structs são particularmente úteis para estruturas de dados pequenas que têm semântica de valor.Structs are particularly useful for small data structures that have value semantics. Números complexos, pontos em um sistema de coordenadas ou pares chave-valor em um dicionário são exemplos de structs.Complex numbers, points in a coordinate system, or key-value pairs in a dictionary are all good examples of structs. O uso de structs, em vez de classes para estruturas de dados pequenas, pode fazer uma grande diferença no número de alocações de memória que um aplicativo executa.The use of structs rather than classes for small data structures can make a large difference in the number of memory allocations an application performs. Por exemplo, o programa a seguir cria e inicializa uma matriz de 100 pontos.For example, the following program creates and initializes an array of 100 points. Com Point implementado como uma classe, 101 objetos separados são instanciados — um para a matriz e um para os elementos de 100.With Point implemented as a class, 101 separate objects are instantiated—one for the array and one each for the 100 elements.

public class PointExample
{
    public static void Main() 
    {
        Point[] points = new Point[100];
        for (int i = 0; i < 100; i++)
            points[i] = new Point(i, i);
    }
}

Uma alternativa é tornar um struct um Ponto.An alternative is to make Point a struct.

struct Point
{
    public int x, y;
    public Point(int x, int y) 
    {
        this.x = x;
        this.y = y;
    }
}

Agora, somente um objeto é instanciado — um para a matriz — e as instâncias Point são armazenadas em linha na matriz.Now, only one object is instantiated—the one for the array—and the Point instances are stored in-line in the array.

Os construtores struct são invocados com o operador new, semelhante a um construtor de classe.Struct constructors are invoked with the new operator, similar to a class constructor. Porém, em vez de alocar dinamicamente um objeto no heap gerenciado e retornar uma referência a ele, um construtor de struct simplesmente retorna o valor do struct (normalmente em um local temporário na pilha), e esse valor é, então, copiado conforme a necessidade.But, instead of dynamically allocating an object on the managed heap and returning a reference to it, a struct constructor simply returns the struct value itself (typically in a temporary location on the stack), and this value is then copied as necessary.

Com classes, é possível que duas variáveis referenciem o mesmo objeto e, portanto, é possível que operações em uma variável afetem o objeto referenciado por outra variável.With classes, it is possible for two variables to reference the same object and thus possible for operations on one variable to affect the object referenced by the other variable. Com structs, as variáveis têm sua própria cópia dos dados e não é possível que as operações em um afetem o outro.With structs, the variables each have their own copy of the data, and it is not possible for operations on one to affect the other. Por exemplo, a saída produzida pelo seguinte fragmento de código depende de o ponto ser uma classe ou um struct.For example, the output produced by the following code fragment depends on whether Point is a class or a struct.

Point a = new Point(10, 10);
Point b = a;
a.x = 20;
Console.WriteLine(b.x);

Se Point for uma classe, a saída será 20 porque a e b referenciam o mesmo objeto.If Point is a class, the output is 20 because a and b reference the same object. Se Point for um struct, a saída será 10 porque a atribuição de a para b cria uma cópia do valor e essa cópia não é afetada pela atribuição seguinte para a.x.If Point is a struct, the output is 10 because the assignment of a to b creates a copy of the value, and this copy is unaffected by the subsequent assignment to a.x.

O exemplo anterior destaca duas das limitações dos structs.The previous example highlights two of the limitations of structs. Primeiro, copiar um struct inteiro é, geralmente, menos eficiente do que copiar uma referência de objeto, então a passagem de atribuição e de valor do parâmetro pode ser mais custosa com structs que com tipos de referência.First, copying an entire struct is typically less efficient than copying an object reference, so assignment and value parameter passing can be more expensive with structs than with reference types. Segundo, com exceção dos parâmetros in, ref e out, não é possível criar referências para structs, o que rege o uso em diversas situações.Second, except for in, ref, and out parameters, it is not possible to create references to structs, which rules out their usage in a number of situations.