Médio C#
readonly struct imutável
Enunciado
Transforme a struct Retangulo em readonly struct com propriedades somente leitura. Adicione um método ComLargura(double novaLargura) que retorna um novo Retangulo com a largura alterada, sem modificar o original. Demonstre no Main.
Requisitos
- Declarar
public readonly struct Retangulo. - Usar propriedades
LarguraeAlturasomente leitura (get). - Implementar
ComLargura(double)retornando nova instância. - No
Main, criarr1, chamarComLargura(10)e imprimir ambos.
Código inicial
using System;
// Implemente a readonly struct Retangulo
class Program
{
static void Main()
{
// Demonstre a imutabilidade
}
}
Saída esperada
r1 = (3, 4)
r2 = (10, 4)
Ver dica
Em readonly struct, todos os campos devem ser readonly. O método ComLargura retorna new Retangulo(novaLargura, Altura).
Mostrar solução
using System;
// readonly struct: imutável após construção
public readonly struct Retangulo
{
public double Largura { get; }
public double Altura { get; }
public Retangulo(double largura, double altura)
{
Largura = largura;
Altura = altura;
}
// Retorna uma nova instância com a largura alterada
public Retangulo ComLargura(double novaLargura) => new Retangulo(novaLargura, Altura);
public override string ToString() => $"({Largura}, {Altura})";
}
class Program
{
static void Main()
{
Retangulo r1 = new Retangulo(3, 4);
Retangulo r2 = r1.ComLargura(10); // novo objeto, r1 intacto
Console.WriteLine($"r1 = {r1}");
Console.WriteLine($"r2 = {r2}");
}
}
Passo a passo
- Declaramos
public readonly struct Retangulo. O modificadorreadonlygarante que todos os campos sejam somente leitura. - Usamos propriedades autoimplementadas
{ get; }para expor os valores sem permitir alteração externa. - O construtor inicializa as propriedades. Como são
readonly, só podem ser atribuídas no construtor. ComLarguracria e retorna um novoRetangulocom a largura desejada, mantendo a altura.- No
Main, chamamosr1.ComLargura(10)e guardamos emr2.r1permanece inalterado. - Imprimimos ambos para confirmar a imutabilidade.
Por que funciona
readonly struct impede modificações após a construção, eliminando bugs de mutação acidental. Métodos que "alteram" retornam novas instâncias, seguindo o padrão funcional. Isso também permite ao compilador evitar cópias defensivas ao passar a struct como argumento in, melhorando desempenho.
Erros comuns
- Tentar atribuir
Largurafora do construtor:r1.Largura = 5;gera erro CS0200 (propriedade somente leitura). - Esquecer
readonlynos campos: se usar campos públicos, o compilador exigereadonlyem cada um; com propriedades{ get; }isso é automático. - Retornar
thisem vez de nova instância:public Retangulo ComLargura(double l) { Largura = l; return this; }não compila em readonly struct.
Outra forma de resolver
Usar um método de extensão ou um with expression (C# 10+):
Retangulo r2 = r1 with { Largura = 10 };
Para isso, a struct precisa ser record struct ou ter propriedades init. É mais conciso, mas exige C# 10+.
Saída esperada
r1 = (3, 4)
r2 = (10, 4)