C# Quiz

40 perguntas sobre o que você estudou no guia, divididas nos três níveis. Muitas mostram um trecho de código e perguntam o que ele mostra: tente responder de cabeça, sem rodar. Todas as respostas foram conferidas de verdade, com o dotnet run do .NET 10 na máquina da Ana (em português, por isso 3,5 com vírgula) e no editor do guia. A correção é na hora; abra "Explicação" para entender o porquê, e o link "Revise" leva à aula do assunto.

Acertos: 0 de 40

Como os trechos funcionam

Os trechos são instruções de nível superior, como num arquivo teste.cs rodado com dotnet run teste.cs. Quando o trecho usa uma classe, um record ou um struct, ela aparece depois das instruções, como no arquivo de verdade. Para conferir uma resposta, cole o trecho numa caixa "Experimente" de qualquer aula, como a de Olá, Mundo, e clique em Rodar.

Ir para: Nível 1 · Nível 2 · Nível 3

Nível 1 · Iniciante

Saída, tipos, operadores, texto, decisões, laços, entrada e arrays.

1. O que este código mostra?

Console.WriteLine(7 / 2);
Explicação

Os dois números são int, então a divisão é inteira: o resultado é 3, e a parte decimal é jogada fora (não arredonda para 4).

Revise: Operadores Aritméticos

2. E este, na máquina da Ana, que está em português?

Console.WriteLine(7 / 2.0);
Explicação

Com um double na conta (2.0), a divisão tem casas decimais. No código, o separador é sempre o ponto; na saída, o C# usa o formato da cultura da máquina, e em pt-BR a casa decimal é a vírgula.

Revise: float, double e decimal e Cultura

3. O que este código mostra?

Console.WriteLine(0.1 + 0.2 == 0.3);
Explicação

O double guarda os números em base 2, e 0,1 e 0,2 não têm representação exata: a soma dá 0,30000000000000004, que não é igual a 0,3. Com decimal (0.1m + 0.2m == 0.3m), dá True. Por isso, dinheiro em decimal.

Revise: float, double e decimal

4. O que este código mostra?

Console.WriteLine("Total: " + 2 + 3);
Explicação

O + é resolvido da esquerda para a direita. "Total: " + 2 junta texto e número e dá o texto "Total: 2"; depois, "Total: 2" + 3 dá "Total: 23". Para somar antes, use parênteses: "Total: " + (2 + 3), ou a interpolação $"Total: {2 + 3}".

Revise: Precedência e Saída

5. O que este código mostra?

int x = 5;
Console.WriteLine(x++ + " " + x);
Explicação

O x++ (pós-fixado) usa o valor atual (5) e só depois soma 1. Quando o segundo x é lido, ele já vale 6. Com ++x, a saída seria 6 6.

Revise: ++ e --

6. Qual é o tipo de preco?

var preco = 19.90;
Explicação

O var não é um tipo: o compilador olha o valor e escolhe. Um número com ponto e sem sufixo é double (preco.GetType() mostra System.Double). Para dinheiro, escreva 19.90m ou decimal preco = 19.90m;.

Revise: Inferência com var

7. O que este código mostra?

Console.WriteLine($"{1234.5m:C}");
Explicação

O formato C (currency, moeda) usa a moeda e os separadores da cultura da máquina: em pt-BR, R$, ponto nos milhares, vírgula nos centavos e sempre duas casas.

Revise: Formatar Números

8. O que este código mostra?

string texto = "Olá";
texto.ToUpper();
Console.WriteLine(texto);
Explicação

Strings são imutáveis: ToUpper() não muda o texto, ele devolve um texto novo, que aqui foi jogado fora. Para guardar, escreva texto = texto.ToUpper();.

Revise: Strings e Métodos de String

9. O que este código mostra?

Console.WriteLine("banana".IndexOf('n') + " " + "banana".IndexOf('z'));
Explicação

As posições começam em 0: b é 0, a é 1, o primeiro n é 2. Quando a letra não existe, IndexOf não lança exceção: devolve -1.

Revise: Métodos de String

10. O que este código mostra?

int[] v = [10, 20, 30];
Console.WriteLine(v[^1]);
Explicação

^1 quer dizer "o primeiro a partir do fim", ou seja, o último elemento. É o mesmo que v[v.Length - 1]. (^0 seria uma posição depois do fim e lançaria exceção.)

Revise: Índices (^) e Intervalos (..)

11. O que este código mostra?

int[] v = [10, 20, 30];
int[] copia = v;
copia[0] = 99;
Console.WriteLine(v[0]);
Explicação

Um array é um tipo de referência: copia = v não copia os números, copia o endereço. As duas variáveis apontam para o mesmo array, então mudar por uma aparece na outra. Para uma cópia de verdade, use v.Clone(), [.. v] ou v.ToArray().

Revise: Arrays e Valor × Referência

12. O que este código mostra?

for (int i = 0; i < 3; i++)
{
    Console.Write(i);
}
Explicação

O i começa em 0 e o laço roda enquanto i < 3: com 0, 1 e 2. Quando i vira 3, a condição é falsa e o laço para antes de mostrar. Write não pula linha, por isso sai tudo junto.

Revise: for

13. Quais números Random.Shared.Next(1, 7) pode sortear?

Explicação

O primeiro número entra no sorteio; o segundo é o limite de fora. Next(1, 7) é um dado: 1, 2, 3, 4, 5 ou 6. Para 1 a 100, Next(1, 101).

Revise: Números Aleatórios

14. O que acontece com este código?

string operacao = "+";
switch (operacao)
{
    case "+":
        Console.WriteLine("soma");
    case "-":
        Console.WriteLine("subtração");
        break;
}
Explicação

Em C e Java, sem break o programa continuaria no case de baixo. O C# proíbe isso, porque quase sempre é um esquecimento: todo case com código tem de terminar com break, return ou throw.

Revise: switch

15. Quantas vezes o A aparece?

do
{
    Console.Write("A");
} while (false);
Explicação

O do while roda o corpo antes de testar a condição: mesmo com false, roda uma vez. Um while (false) { … } não rodaria nenhuma.

Revise: do while

16. A Ana digitou abc. O que acontece com int.Parse(Console.ReadLine()!)?

Explicação

Parse confia que o texto é um número. Para o que o usuário digita, use int.TryParse(texto, out int numero), que devolve false em vez de lançar exceção.

Revise: Parse e TryParse e Ler do Teclado

17. O que este código mostra?

Console.WriteLine(Math.Round(2.5) + " " + Math.Round(3.5));
Explicação

Por padrão, Math.Round usa o arredondamento bancário: no meio exato (,5), vai para o número par mais próximo. 2,5 vira 2 e 3,5 vira 4. Para o arredondamento da escola, use Math.Round(2.5, MidpointRounding.AwayFromZero), que dá 3.

Revise: Matemática (Math)

18. O que este código mostra?

int trezentos = 300;
Console.WriteLine((int)7.9 + " " + (byte)trezentos);
Explicação

O cast (int) corta a parte decimal (não arredonda): 7,9 vira 7. Um byte vai de 0 a 255; o cast fica só com os 8 bits de baixo de 300, que dão 300 − 256 = 44. Sem checked, ninguém avisa. Com checked((byte)trezentos), viria uma OverflowException.

Revise: Conversão de Tipos e Inteiros

19. O que o erro CS0165: Uso de variável local não atribuída "total" quer dizer?

Explicação

O C# não deixa ler uma variável local sem valor, para você nunca usar um "lixo" da memória. Dê um valor inicial (int total = 0;) ou garanta que todo caminho do código atribua antes de ler. (Uma variável que não existe é o CS0103; declarada duas vezes, o CS0128.)

Revise: Variáveis e Lendo Erros do Compilador

20. O que este código mostra?

int[] v = [99, 20, 30];
Console.WriteLine(string.Join(" | ", v[..2]));
Explicação

O intervalo ..2 vai do começo até a posição 2, sem incluir a 2: as posições 0 e 1. O fim de um intervalo nunca entra.

Revise: Índices (^) e Intervalos (..)

Nível 2 · Intermediário

Métodos, null, classes, herança, tipos de valor e exceções.

21. O que este código mostra?

int? idade = null;
Console.WriteLine(idade ?? 0);
Explicação

int? é um inteiro que aceita null. O ?? é o "valor reserva": se o da esquerda for null, usa o da direita.

Revise: null e Tipos Anuláveis e Operadores ??, ?. e ??=

22. O que este código mostra?

string? apelido = null;
Console.WriteLine($"[{apelido?.Length}]");
Explicação

O ?. só lê Length se apelido não for null; se for, o resultado inteiro é null, e na interpolação um null vira texto vazio. Sem o ?, apelido.Length lançaria NullReferenceException (e o compilador avisaria com CS8602).

Revise: Operadores ??, ?. e ??= e Referências Anuláveis

23. O que este código mostra?

Console.WriteLine(new Ponto(1, 2) == new Ponto(1, 2));
Console.WriteLine(new PontoClasse(1, 2) == new PontoClasse(1, 2));

record Ponto(int X, int Y);
class PontoClasse(int x, int y) { public int X = x; public int Y = y; }
Explicação

Um record compara pelo conteúdo: dois pontos com os mesmos valores são iguais. Uma classe comum compara pela referência: dois new são dois objetos diferentes, mesmo com os mesmos valores.

Revise: Records e A Classe object (Equals)

24. O que este código mostra?

var a = new Ponto { X = 1 };
var b = a;
b.X = 5;
Console.WriteLine(a.X);

struct Ponto { public int X; }
Explicação

Ponto é um struct, um tipo de valor: b = a faz uma cópia inteira. Mudar b não mexe em a. Se Ponto fosse uma class, a resposta seria 5.

Revise: Structs e Valor × Referência

25. O que este código mostra?

var compras = new List<string> { "arroz" };
var mesmaLista = compras;
mesmaLista.Add("feijão");
Console.WriteLine(compras.Count);
Explicação

List é uma classe: as duas variáveis guardam o endereço da mesma lista no heap. O Add por uma aparece na outra.

Revise: Valor × Referência e Memória e Coletor de Lixo

26. Numa classe Conta, o que public decimal Saldo { get; private set; } permite?

Explicação

É o encapsulamento: o saldo só muda pelos métodos da classe (Depositar, Sacar), que conferem as regras.

Revise: Propriedades, Encapsulamento e Conta Bancária

27. O que este código mostra?

Animal bicho = new Cachorro();
Console.WriteLine(bicho.Falar() + " " + bicho.Mover());

class Animal
{
    public virtual string Falar() => "...";
    public string Mover() => "anda";
}
class Cachorro : Animal
{
    public override string Falar() => "Au";
    public new string Mover() => "corre";
}
Explicação

Falar é virtual e o cachorro faz override: vale a versão do objeto de verdade, um Cachorro (polimorfismo). Mover não é virtual; o new só esconde o da mãe, e, por uma variável do tipo Animal, quem roda é o Mover do Animal.

Revise: virtual e override e Polimorfismo

28. Uma classe filha tem o construtor public ContaPoupanca(string titular), sem : base(…), e a mãe só tem public Conta(string titular). O que acontece?

Explicação

Todo construtor da filha chama um construtor da mãe. Sem : base(titular), o C# tenta o construtor sem parâmetros. Como a Conta só tem o que pede o titular, a compilação falha.

Revise: base e Herança

29. O que este código mostra?

try
{
    Console.Write("A ");
    int zero = 0;
    Console.Write(10 / zero);
    Console.Write("B ");
}
catch (DivideByZeroException)
{
    Console.Write("C ");
}
finally
{
    Console.Write("F");
}
Explicação

A divisão inteira por zero lança DivideByZeroException: o resto do try (o B) é pulado, o catch roda (C) e o finally roda sempre, com ou sem exceção (F).

Revise: try e catch e finally

30. Dentro de um catch (Exception ex), qual é a forma certa de relançar a exceção sem perder de onde ela veio?

Explicação

throw; sozinho relança a mesma exceção com o rastro original (o stack trace). throw ex; recomeça o rastro na linha do catch, e você perde a linha em que o erro nasceu (o analisador avisa com CA2200).

Revise: throw

31. O que este código mostra?

Console.WriteLine(Contador.Total);
new Contador();
new Contador();
Console.WriteLine(Contador.Total);

class Contador
{
    public static int Total;
    public Contador() => Total++;
}
Explicação

Um campo static é da classe, não de cada objeto: existe um Total só, que começa em 0 (o valor padrão de int), e cada construtor soma 1 nele.

Revise: static

32. Num record record Aluno(string Nome, double Nota);, a Ana escreveu bruno.Nota = 8;. O que acontece, e como trocar a nota?

Explicação

As propriedades de um record posicional só recebem valor na criação. A expressão with cria um record novo, igual ao antigo, com as propriedades indicadas trocadas.

Revise: Records e readonly e init

Nível 3 · Avançado

Coleções, LINQ, arquivos, assíncrono e ferramentas.

33. O que acontece neste código?

var estoque = new Dictionary<string, int>();
Console.WriteLine(estoque["caneta"]);
Explicação

Ler uma chave que não existe com [ ] lança exceção. Para perguntar com segurança, use TryGetValue("caneta", out int qtd) ou GetValueOrDefault("caneta").

Revise: Dictionary

34. O que este código mostra?

var numeros = new List<int> { 1, 2, 3 };
var grandes = numeros.Where(n => n > 1);
numeros.Add(10);
Console.WriteLine(grandes.Count());
Explicação

A consulta LINQ tem execução adiada: o Where não filtra na hora, só guarda a receita. Ela roda no Count(), quando a lista já tem o 10: os maiores que 1 são 2, 3 e 10. Para "fotografar" o resultado na hora, use .ToList().

Revise: O que é LINQ

35. Numa lista vazia de decimal, o que Sum() e Average() fazem?

Explicação

A soma de nada é zero, sem problema. Mas a média de nada não existe (seria 0 dividido por 0), e o LINQ avisa com a exceção. Confira com Any() antes, ou use DefaultIfEmpty().

Revise: Agregar (Count, Sum, Average)

36. O que este código mostra?

var compras = new HashSet<string> { "arroz" };
Console.WriteLine(compras.Add("arroz") + " " + compras.Count);
Explicação

Um HashSet não guarda repetidos. O Add de um item que já está lá não lança exceção: devolve false e não muda nada.

Revise: HashSet

37. Depois de pôr 1, 2 e 3 (nessa ordem) numa Queue<int> com Enqueue e numa Stack<int> com Push, o que fila.Dequeue() e pilha.Pop() devolvem?

Explicação

A fila é "primeiro a entrar, primeiro a sair", como a fila do banco: sai o 1. A pilha é "último a entrar, primeiro a sair", como uma pilha de pratos: sai o 3, que está no topo.

Revise: Queue e Stack

38. A Ana remove itens de uma List com Remove dentro de um foreach sobre a mesma lista. O que acontece?

Explicação

O foreach confere se a lista mudou debaixo dele e, se mudou, lança a exceção na próxima volta. Ache primeiro e remova depois, ou use RemoveAll(condição).

Revise: List<T> e Agenda de Contatos

39. Num método async Task<string> LerAsync(), o que o await em string texto = await File.ReadAllTextAsync("notas.txt"); faz?

Explicação

O await "desembrulha" a Task<string>: enquanto a leitura não termina, o método fica pausado e a thread fica livre para outras coisas; quando termina, o método continua com o texto. Esquecer o await ao chamar um método async dá o aviso CS4014.

Revise: async e await

40. Quando o coletor de lixo (GC) pode liberar um objeto?

Explicação

O coletor libera o que não é mais alcançável, e não tem hora marcada. Por isso, arquivos e conexões se fecham com using (que chama o Dispose na hora), e não esperando o coletor. E uma lista static que só cresce mantém tudo alcançável: é o "vazamento" de memória do C#.

Revise: Memória e Coletor de Lixo e using e IDisposable

E agora?

Errou alguma? Abra a aula do "Revise", leia a seção do assunto e pratique nas caixas "Experimente". Para consultar rapidamente um termo, use o Glossário; para juntar tudo num programa, os Projetos.