Desafio C#

Métodos com `ref`, `in` e parâmetros nomeados

Enunciado

Crie uma classe Calculadora com:

  • Um método Incrementar que recebe um int por ref e o incrementa em 1.
  • Um método CalcularArea que recebe um double por in (raio) e retorna a área do círculo (π * raio²).
  • Um método Formatar que recebe um número double, um número de casas decimais (opcional, padrão 2) e um prefixo (opcional, padrão "R$"). Use parâmetros nomeados na chamada. No Main, demonstre o uso de ref, in e parâmetros nomeados.

Requisitos

  • Incrementar(ref int x) deve modificar a variável original.
  • CalcularArea(in double raio) deve usar in e retornar Math.PI * raio * raio.
  • Formatar(double valor, int casas = 2, string prefixo = "R$") deve retornar uma string formatada.
  • No Main, chame Formatar usando parâmetros nomeados fora de ordem.
  • Imprima os resultados de forma clara.

Código inicial

using System;

class Calculadora
{
    // TODO: implementar Incrementar com ref
    // TODO: implementar CalcularArea com in
    // TODO: implementar Formatar com parâmetros opcionais
}

class Program
{
    static void Main()
    {
        // TODO: testar os métodos
    }
}

Saída esperada

Valor após incremento: 11
Área do círculo: 78,54
Formatado: R$ 1.234,57
Formatado: $ 1234.57
Ver dica

Para CalcularArea, use Math.PI * raio * raio. Para Formatar, use valor.ToString($"F{casas}") e concatene o prefixo. Na chamada com parâmetros nomeados, use casas: 2, prefixo: "$".

Mostrar solução
using System;

class Calculadora
{
    // Modifica o valor original via ref
    public void Incrementar(ref int x) => x++;

    // Recebe o raio por referência somente leitura (in)
    public double CalcularArea(in double raio) => Math.PI * raio * raio;

    // Parâmetros opcionais: casas decimais e prefixo
    public string Formatar(double valor, int casas = 2, string prefixo = "R$")
    {
        // Formata o número com a quantidade de casas e adiciona o prefixo
        return $"{prefixo} {valor.ToString($"F{casas}")}";
    }
}

class Program
{
    static void Main()
    {
        var calc = new Calculadora();

        // Testa ref
        int numero = 10;
        calc.Incrementar(ref numero);
        Console.WriteLine($"Valor após incremento: {numero}"); // 11

        // Testa in
        double raio = 5.0;
        double area = calc.CalcularArea(in raio);
        Console.WriteLine($"Área do círculo: {area:F2}"); // 78,54

        // Testa parâmetros nomeados fora de ordem
        string formatado1 = calc.Formatar(1234.567, casas: 2, prefixo: "R$");
        Console.WriteLine($"Formatado: {formatado1}"); // R$ 1.234,57

        string formatado2 = calc.Formatar(1234.567, prefixo: "$", casas: 2);
        Console.WriteLine($"Formatado: {formatado2}"); // $ 1234.57
    }
}

Passo a passo

  1. A classe Calculadora contém três métodos que demonstram ref, in e parâmetros opcionais/nomeados.
  2. Incrementar usa ref int x e faz x++; a alteração afeta a variável original.
  3. CalcularArea usa in double raio para evitar cópia e deixar claro que o valor não será modificado.
  4. Formatar tem dois parâmetros opcionais: casas (padrão 2) e prefixo (padrão "R$").
  5. Dentro de Formatar, usamos valor.ToString($"F{casas}") para formatar com casas decimais fixas.
  6. No Main, chamamos Formatar com parâmetros nomeados em ordens diferentes para mostrar a flexibilidade.
  7. A saída usa F2 para formatar a área com duas casas decimais.

Por que funciona

ref permite modificar a variável original, pois passa o endereço de memória. in também passa por referência, mas impede modificações, sendo útil para grandes structs. Parâmetros opcionais e nomeados permitem chamadas mais legíveis e flexíveis, especialmente quando há muitos argumentos.

Erros comuns

  • Esquecer ref na chamada: calc.Incrementar(numero) não compila; é necessário ref numero.
  • Tentar modificar parâmetro in: dentro de CalcularArea, raio = 10 gera erro CS8331. Use in apenas para leitura.
  • Parâmetro opcional antes do obrigatório: Formatar(double valor, int casas = 2, string prefixo) não compila porque prefixo não tem valor padrão. Todos os opcionais devem vir depois dos obrigatórios.
  • Formatação com cultura errada: valor.ToString("F2") usa a cultura atual; em alguns sistemas, o separador decimal pode ser ponto. Para forçar vírgula, use CultureInfo.

Outra forma de resolver

Poderia usar ref readonly em vez de in para parâmetros somente leitura, mas in é mais comum e suficiente. Para formatação, poderia usar string.Format ou interpolação diretamente.

Saída esperada

Valor após incremento: 11
Área do círculo: 78,54
Formatado: R$ 1.234,57
Formatado: $ 1234.57