Olá, José. Como vai?
O seu código em C# ficou fantástico! A estrutura do jogo do número secreto está muito bem desenhada, as mensagens de feedback ("é maior" ou "é menor") dão uma ótima experiência para o jogador e o console vai rodar perfeitamente.
Gostaria de destacar o excelente nível técnico da sua função ValidarDados(). O uso do byte.TryParse combinado com a cláusula out mostra que você já domina boas práticas de tratamento de erros e segurança de dados em C#. Fazer essa validação impede que o programa sofra um travamento (crash) caso o usuário digite uma letra ou uma palavra por engano, mantendo o fluxo do jogo seguro e robusto.
Para agregar ainda mais valor aos seus estudos sobre laços de repetição, vale notar uma excelente escolha arquitetural que você fez no corpo principal do programa: o uso do do/while (faça enquanto).
Muitos desenvolvedores têm dúvidas sobre quando usar o while tradicional e quando usar o do/while. O seu projeto é o cenário didático perfeito para ilustrar essa diferença:
while tradicional: Analisa a condição antes de rodar o bloco. Se a condição for falsa logo de início, o código de dentro nunca é executado.do/while (o seu caso): Executa o bloco de código de dentro pelo menos uma vez antes de checar a condição pela primeira vez. Isso é perfeito para jogos de adivinhação, pois o jogador obrigatoriamente precisa fazer a primeira tentativa antes que o sistema possa validar se ele acertou ou errou.
Para visualizar como o fluxo de execução do do/while garante essa primeira rodada obrigatória antes de testar a condição no final, observe a estrutura lógica do laço:
Como uma sugestão de melhoria sutil de legibilidade e consistência, veja o nome da variável interna da sua função de validação: string quantidade = Console.ReadLine()!;. Como o jogo é sobre adivinhação de números ou tentativas, mudar o nome dessa variável de quantidade para algo como entradaUsuario ou textoDigitado deixaria o seu código ainda mais intuitivo para outros programadores que lerem o seu projeto no futuro.
Parabéns pela excelente solução, pela modularização com funções e pelo ótimo uso dos tipos primitivos (como o byte, que economiza memória perfeitamente para números pequenos)!
Espero que possa ter lhe ajudado!