Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

[Dúvida] get e set customizados

No capítulo 05 aula 03 do curso C#: consumindo API, gravando arquivos e utilizando o LINQ, ao invés de utilizar uma lista com as notas musicais, eu quis escrever um get customizado para a propriedade Tonalidade, só que não entendi porque a versão 01 não deu certo (Erro: Stack overflow =) ) e a versão 02 deu certo. Tenho certeza que é algo básico, mas eu não consegui entender o porquê.

Versão 01

public string Tonalidade
{
    get
    {
        switch (Key)
        {
            case 0:
                Tonalidade = "C";
                break;
            case 1:
                Tonalidade = "C#";
                break;
            case 2:
                Tonalidade = "D";
                break;
            case 3:
                Tonalidade = "D#";
                break;
            case 4:
                Tonalidade = "E";
                break;
            case 5:
                Tonalidade = "F";
                break;
            case 6:
                Tonalidade = "F#";
                break;
            case 7:
                Tonalidade = "G";
                break;
            case 8:
                Tonalidade = "G#";
                break;
            case 9:
                Tonalidade = "A";
                break;
            case 10:
                Tonalidade = "A#";
                break;
            case 11:
                Tonalidade = "B";
                break;
            default:
                Console.WriteLine("Erro: Opção não mapeada!");
                Tonalidade = "";
                break;
        }

        return Tonalidade;
    }

    set
    {
        Tonalidade = value;
    }
}

Versão 02

public string Tonalidade
{
    get
    {
        switch (Key)
        {
            case 0:
                return "C";
            case 1:
                return "C#";
            case 2:
                return "D";
            case 3:
                return "D#";
            case 4:
                return "E";
            case 5:
                return "F";
            case 6:
                return "F#";
            case 7:
                return "G";
            case 8:
                return "G#";
            case 9:
                return "A";
            case 10:
                return "A#";
            case 11:
                return "B";
            default:
                Console.WriteLine("Erro: Opção não mapeada!");
                return "";
        }
    }
}
2 respostas
solução!

Oi, Otavio! Tudo bem?

A razão pela qual a versão 01 está causando um Stack Overflow é devido a uma chamada recursiva infinita.

Analisando o código abaixo:

public string Tonalidade
{
    get
    {
        switch (Key)
        {
            case 0:
                Tonalidade = "C";
                break;
            ...
        }

        return Tonalidade;
    }

    set
    {
        Tonalidade = value;
    }
}

Podemos perceber que quando estamos fazendo Tonalidade = "C";, na verdade, estamos chamando o set da propriedade Tonalidade. No set, estamos novamente atribuindo um valor a Tonalidade, o que resulta em outra chamada ao set, o que leva a um ciclo infinito de chamadas set, causando um estouro de pilha (Stack Overflow).

Já na versão 02, estamos simplesmente retornando uma string, sem fazer nenhuma atribuição à propriedade Tonalidade. Isso evita a chamada recursiva e, portanto, o código funciona como esperado.

Lembrando que o get deve ser usado para recuperar valores e não deve modificar o estado interno da propriedade, enquanto o set é usado para modificar o estado interno da propriedade.

Espero ter ajudado! Caso tenha ficado alguma dúvida, sinta-se à vontade em comunicar, estou à disposição!

Um forte abraço e bons estudos!

Caso este post tenha te ajudado, por favor, marcar como solucionado ✓

Show! Obrigado pela ajuda Sarah. Agora ficou claro o que eu estava fazendo de errado.