Desafio C#
Record struct e igualdade por valor
Enunciado
Crie um record struct Coordenada com as propriedades X e Y (int). No Main, crie duas coordenadas iguais e uma diferente. Use with para criar uma cópia alterando X. Exiba a igualdade entre as coordenadas e também entre a cópia e a original. Além disso, mostre que record struct é um tipo de valor usando Equals e ReferenceEquals.
Requisitos
- Declarar
record struct CoordenadacomXeY. - Criar instâncias, comparar com
==e usarwith. - Demonstrar que é tipo de valor com
ReferenceEquals(deve retornarFalse).
Código inicial
using System;
// TODO: declarar o record struct Coordenada
public class Program
{
public static void Main()
{
// TODO: criar coordenadas, comparar e usar with
}
}
Saída esperada
c1 == c2: True
c1 == c3: False
copia == c1: False
ReferenceEquals(c1, c2): False
Ver dica
record struct é tipo de valor; ReferenceEquals sempre retorna False para tipos de valor, mesmo que sejam iguais.
Mostrar solução
using System;
// record struct: tipo de valor com igualdade por valor
public record struct Coordenada(int X, int Y);
public class Program
{
public static void Main()
{
var c1 = new Coordenada(10, 20);
var c2 = new Coordenada(10, 20);
var c3 = new Coordenada(10, 30);
// Igualdade por valor
Console.WriteLine($"c1 == c2: {c1 == c2}"); // True
Console.WriteLine($"c1 == c3: {c1 == c3}"); // False
// with cria uma cópia alterando X
var copia = c1 with { X = 15 };
Console.WriteLine($"copia == c1: {copia == c1}"); // False
// ReferenceEquals sempre False para tipos de valor
Console.WriteLine($"ReferenceEquals(c1, c2): {ReferenceEquals(c1, c2)}");
}
}
Passo a passo
- Declaramos
Coordenadacomorecord structposicional, que gera propriedadesXeYe implementa igualdade por valor. - Criamos
c1ec2com os mesmos valores, ec3com Y diferente. c1 == c2compara os valores deXeYe retornaTrue.c1 == c3retornaFalseporqueYdifere.c1 with { X = 15 }cria uma nova instância deCoordenadacomXalterado eYcopiado.copia == c1retornaFalseporqueXé diferente.ReferenceEquals(c1, c2)recebe os structs em caixas separadas (boxing) e compara referências, retornandoFalse.
Por que funciona
record struct combina a semântica de tipo de valor (armazenado na pilha, copiado por valor) com a igualdade por valor dos records. O operador with funciona tanto para record class quanto para record struct, gerando uma nova instância com as alterações. ReferenceEquals não faz sentido para tipos de valor, pois cada boxing cria um novo objeto.
Erros comuns
- Declarar
record class Coordenadaem vez derecord struct:ReferenceEqualspoderia retornarTruese fosse a mesma referência, mas o enunciado pede tipo de valor. - Usar
==esperando igualdade por referência: emrecord struct,==compara valores, não referências. - Esquecer que
withemrecord structretorna uma nova instância; não modifica a original.
Outra forma de resolver
Se precisar de um tipo de valor sem igualdade por valor, use struct comum e implemente IEquatable<T> manualmente. Mas record struct é mais conciso e já traz a igualdade por valor.
Saída esperada
c1 == c2: True
c1 == c3: False
copia == c1: False
ReferenceEquals(c1, c2): False