Introdução: por que o construtor da classe base não é apenas "teoria chata"?
\n\nImagine que você está construindo uma casa. Você tem a fundação (classe base) e a casa em si (classe derivada). A fundação já está pronta, mas para a casa ficar firme, é preciso "conectá-la" corretamente à fundação. Em C#, essa "conexão" é feita pela chamada ao construtor da classe base através da palavra-chave base.
Este é um daqueles tópicos que geram milhares de perguntas no Stack Overflow. Por quê? Porque sem entender esse mecanismo, seu código ou não compila ou funciona de forma imprevisível. Neste artigo, vamos abordar a chamada ao construtor da classe base em C# do simples ao complexo: com exemplos, armadilhas e cenários reais.
\n\nO que você aprenderá neste artigo?
\n- \n
- Como funciona a herança de construtores em C#. \n
- Quando e por que chamar explicitamente
base(). \n - Como passar parâmetros para o construtor da classe base. \n
- Erros típicos e como evitá-los. \n
- Técnicas avançadas: cadeias de construtores e sobrecarga. \n
1. Fundamentos: o que é o construtor da classe base?
\n\nEm C#, cada classe pode ter um ou mais construtores. Quando você cria uma instância de uma classe derivada, o construtor da classe base é chamado primeiro. Isso garante que todos os campos e propriedades do "pai" sejam inicializados antes que o "filho" comece a funcionar.
\n\nSe você não especificar explicitamente qual construtor da classe base chamar, o compilador tentará chamar o construtor padrão (sem parâmetros). Se ele não existir, você receberá um erro de compilação.
\n\nExemplo 1: chamada implícita (tudo simples)
\npublic class Animal\n{\n public string Name { get; set; }\n\n public Animal()\n {\n Name = "Animal desconhecido";\n Console.WriteLine("Animal: construtor sem parâmetros");\n }\n}\n\npublic class Dog : Animal\n{\n public Dog()\n {\n Console.WriteLine("Dog: construtor");\n }\n}\n\n// Uso\nDog dog = new Dog();\n// Saída:\n// Animal: construtor sem parâmetros\n// Dog: construtor\n\nAqui, Dog chama implicitamente Animal(). Tudo funciona porque Animal tem um construtor padrão.
2. Problema: quando não há construtor padrão
\n\nAgora imagine que a classe base exija parâmetros obrigatórios. Por exemplo, um animal deve ter um nome. Se removermos o construtor sem parâmetros, o código para de compilar.
\n\nExemplo 2: erro de compilação
\npublic class Animal\n{\n public string Name { get; }\n\n public Animal(string name) // único construtor\n {\n Name = name;\n }\n}\n\npublic class Dog : Animal\n{\n // Erro CS7036: "Animal" não contém um construtor que aceita 0 argumentos\n public Dog() \n {\n }\n}\n\nO compilador grita: "Ei, não sei como inicializar Animal sem um nome!". A solução é chamar explicitamente o construtor da classe base usando base.
3. A palavra-chave base: chamada explícita do construtor
\n\nA palavra-chave base em C# é usada para acessar membros da classe base. No contexto de construtores, ela permite especificar qual construtor do pai deve ser chamado e com quais argumentos.
Sintaxe:
\npublic class ClasseDerivada : ClasseBase\n{\n public ClasseDerivada(parâmetros) : base(argumentos)\n {\n // corpo do construtor\n }\n}\n\nOs dois pontos e base(argumentos) são colocados imediatamente após a assinatura do construtor, antes do corpo.
Exemplo 3: corrigindo o erro
\npublic class Animal\n{\n public string Name { get; }\n\n public Animal(string name)\n {\n Name = name;\n Console.WriteLine($"Animal: criado {name}");\n