C# Tipos Intermediário
Structs vs classes
Em C#, structs e classes são tipos de dados, mas com semântica diferente. Classes são tipos de referência: a variável guarda um endereço para o objeto na heap. Structs são tipos de valor: a variável guarda os dados diretamente, geralmente na pilha (ou inline no objeto que a contém).
Isso significa que atribuir uma struct copia todos os campos, enquanto atribuir uma classe copia a referência. Modificar a cópia de uma struct não afeta o original; modificar o objeto apontado por uma referência afeta ambos.
Structs não podem herdar de outra struct ou classe (exceto System.ValueType), não podem ter construtor sem parâmetros explícito (antes do C# 10) e são seladas. Classes suportam herança, polimorfismo e podem ser null.
Use struct para tipos pequenos (geralmente ≤ 16 bytes), imutáveis e de vida curta, como DateTime, Guid, Point. Use readonly struct para garantir imutabilidade e evitar cópias desnecessárias. Use class quando precisar de identidade, herança ou comportamento polimórfico.
Pontos-chave
- Structs têm semântica de valor: atribuições copiam os dados; classes têm semântica de referência: atribuições copiam o endereço.
readonly structimpede que os campos sejam modificados após a construção, evitando efeitos colaterais em cópias.- Structs são mais eficientes para pequenos dados imutáveis, pois evitam alocação na heap e coleta de lixo.
- Classes são preferíveis quando há herança, polimorfismo, identidade ou estado mutável compartilhado.
- Cuidado: structs mutáveis podem causar bugs ao serem passadas como argumento ou armazenadas em coleções.
using System;
// Struct: tipo de valor (cópia independente)
public struct PontoStruct
{
public int X;
public int Y;
public PontoStruct(int x, int y)
{
X = x;
Y = y;
}
public override string ToString() => $"({X}, {Y})";
}
// Class: tipo de referência (compartilha o mesmo objeto)
public class PontoClass
{
public int X;
public int Y;
public PontoClass(int x, int y)
{
X = x;
Y = y;
}
public override string ToString() => $"({X}, {Y})";
}
class Program
{
static void Main()
{
// Struct: atribuição copia os valores
PontoStruct s1 = new PontoStruct(1, 2);
PontoStruct s2 = s1; // cópia independente
s2.X = 99;
Console.WriteLine($"Struct: s1 = {s1}, s2 = {s2}");
// Class: atribuição copia a referência
PontoClass c1 = new PontoClass(1, 2);
PontoClass c2 = c1; // mesma referência
c2.X = 99;
Console.WriteLine($"Class: c1 = {c1}, c2 = {c2}");
}
}