Struct ou Class em C#: quando escolher o quê para iniciantes?

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Struct ou Class em C#: o debate eterno entre iniciantes e profissionais

\n\n

Você já se perguntou por que em C# existem duas formas muito parecidas de criar seu próprio tipo de dados — class e struct? E por que no Stack Overflow a pergunta «When should I use a struct rather than a class in C#?» acumula milhares de visualizações e centenas de respostas? A questão é que, por trás da aparente simplicidade, existe uma nuance profunda que pode tanto acelerar seu programa quanto transformá-lo em um foco de bugs.

\n\n

Neste artigo, vamos analisar como struct difere de class, quando usar struct e quando é melhor esquecer que ela existe. Sem termos complicados, com exemplos práticos e dicas úteis. Vamos lá!

\n\n

Diferença principal: pilha ou heap?

\n\n

O ponto mais importante a entender são os tipos de valor (value types) e os tipos de referência (reference types).

\n\n
    \n
  • Class — tipo de referência. O objeto é armazenado no heap gerenciado, e a variável contém apenas uma referência (endereço) para esse objeto.
  • \n
  • Struct — tipo de valor (value type). A variável armazena os próprios dados diretamente na pilha (stack) ou dentro de outro objeto.
  • \n
\n\n

Parece abstrato? Vamos a um exemplo. Imagine que os dados são um livro. Class é o título do livro e o número da estante onde ele está na biblioteca. Struct é o próprio livro que você carrega no bolso. Quando você passa um class para um método, você passa o número da estante. Quando passa um struct, você entrega uma cópia do livro.

\n\n

Exemplo de código: class vs struct

\n\n
public class PointClass\n{\n    public int X { get; set; }\n    public int Y { get; set; }\n\n    public PointClass(int x, int y)\n    {\n        X = x;\n        Y = y;\n    }\n}\n\npublic struct PointStruct\n{\n    public int X { get; set; }\n    public int Y { get; set; }\n\n    public PointStruct(int x, int y)\n    {\n        X = x;\n        Y = y;\n    }\n}\n\n// Uso\nvar pointClass = new PointClass(10, 20);\nvar pointStruct = new PointStruct(10, 20);\n\n// Passagem para método\nvoid ModifyPointClass(PointClass p) { p.X = 100; }\nvoid ModifyPointStruct(PointStruct p) { p.X = 100; }\n\nModifyPointClass(pointClass);   // pointClass.X se torna 100\nModifyPointStruct(pointStruct); // pointStruct.X permanece 10 — cópia!\n
\n\n

Viu? Struct é copiada ao ser passada. Essa é a diferença chave que determina quando usá-la.

\n\n

Quando struct é sua amiga: 3 casos de ferro

\n\n

A Microsoft recomenda usar struct se seu tipo de dados atender a TODAS as seguintes condições:

\n\n

1. Dados pequenos e simples

\n

Struct é ideal para conjuntos de dados pequenos (recomenda-se no máximo 16-24 bytes). Por exemplo, ponto, cor, vetor, número complexo, coordenadas.

\n\n
public struct RgbColor\n{\n    public byte R { get; }\n    public byte G { get; }\n    public byte B { get; }\n\n    public RgbColor(byte r, byte g, byte b)\n    {\n        R = r;\n        G = g;\n        B = b;\n    }\n}\n
\n\n

Por quê? Porque structs pequenas são copiadas rapidamente, e o armazenamento na pilha reduz a carga no coletor de lixo (GC).

\n\n

2. Objetos de curta duração e imutáveis

\n

Se seus dados são valores imutáveis (immutable), struct é uma ótima escolha. Por exemplo, coordenadas no mapa: você não altera um ponto, cria um novo.

\n\n
public struct GeoLocation\n{\n    public double Latitude { get; }\n    public double Longitude { get; }\n\n    public GeoLocation(double lat, double lon)\n    {\n        Latitude = lat;\n        Longitude = lon;\n    }\n\n    public GeoLocation MoveNorth(double meters)\n    {\n        // Retorna uma nova instância, não altera a antiga\n        return new GeoLocation(Latitude + meters / 111111.0, Longitude);\n    }\n}\n
\n\n

3. Desempenho crítico

Blogs

Book Recommendations