Campos de Suporte
Parte da seção Programação Orientada a Objetos do Journey de C# da Coddy — lição 17 de 70.
Propriedades autoimplementadas são convenientes, mas às vezes você precisa de mais controle sobre como uma propriedade armazena ou recupera seu valor. É aí que entram os backing fields (campos de suporte). Um backing field é um campo privado que armazena os dados reais de uma propriedade.
public class Product
{
private decimal _price; // Campo de suporte
public decimal Price
{
get { return _price; }
set { _price = value; }
}
}Isso parece um trabalho extra em comparação com as auto-properties, mas os backing fields permitem que você adicione lógica. Por exemplo, você pode validar os dados antes de armazená-los:
public class Product
{
private decimal _price;
public decimal Price
{
get => _price;
set => _price = value < 0 ? 0 : value;
}
}Agora, os preços negativos tornam-se automaticamente zero. Você também pode transformar dados ao ler ou escrever, registrar alterações ou disparar outras ações.
A convenção de nomenclatura de backing field geralmente usa um prefixo de sublinhado (_price) ou letras minúsculas (price) para distingui-lo da propriedade.
Quando você usa propriedades autoimplementadas como public decimal Price { get; set; }, o compilador na verdade cria um campo de suporte (backing field) oculto para você. Campos de suporte explícitos oferecem o mesmo armazenamento com controle total sobre o comportamento.
Desafio
FácilVamos construir um sistema de sensor de temperatura que utiliza campos de suporte (backing fields) para validar e transformar dados conforme eles são armazenados e recuperados.
Você criará dois arquivos para organizar seu código:
TemperatureSensor.cs: Defina uma classeTemperatureSensorno namespaceSensors. Este sensor mede a temperatura em Celsius, mas precisamos garantir que as leituras permaneçam dentro de limites válidos. Use campos de suporte para implementar o seguinte:- Uma propriedade
Location(string) com um campo de suporte_location. Ao definir a localização, se o valor for nulo ou vazio, armazene"Unknown"em vez disso. - Uma propriedade
Temperature(double) com um campo de suporte_temperature. Ao definir a temperatura, limite o valor entre-50e150(se for menor que -50, armazene -50; se for maior que 150, armazene 150). - Uma propriedade somente leitura
TemperatureFahrenheitque calcula e retorna a temperatura em Fahrenheit usando a fórmula:(celsius * 9 / 5) + 32. Isso deve usar o campo de suporte diretamente. - Um construtor que aceita a localização e os valores iniciais de temperatura.
- Uma propriedade
Program.cs: No seu arquivo principal, crie um sensor usando valores de entrada e exiba suas leituras. Em seguida, atualize a temperatura com um segundo valor de entrada e mostre as leituras atualizadas.
Você receberá três entradas:
- Localização do sensor
- Leitura de temperatura inicial
- Leitura de temperatura atualizada
Imprima a saída neste formato:
Sensor: {Location}
Temperature: {Temperature}C ({TemperatureFahrenheit}F)
Updated Temperature: {Temperature}C ({TemperatureFahrenheit}F)Por exemplo, se as entradas forem Lab Room, 25, e 200, a saída deve ser:
Sensor: Lab Room
Temperature: 25C (77F)
Updated Temperature: 150C (302F)Observe como a segunda leitura de 200 é limitada a 150 porque excede a temperatura máxima válida. Seus campos de suporte oferecem esse controle sobre como os dados são armazenados!
Folha de consulta
Um backing field (campo de suporte) é um campo privado que armazena os dados reais de uma propriedade, permitindo que você adicione lógica personalizada para obter e definir valores.
Sintaxe Básica de Backing Field
public class Product
{
private decimal _price; // Backing field
public decimal Price
{
get { return _price; }
set { _price = value; }
}
}Sintaxe de Corpo de Expressão (Expression-Bodied)
public decimal Price
{
get => _price;
set => _price = value;
}Adicionando Lógica de Validação
Backing fields permitem que você valide ou transforme dados antes de armazená-los:
private decimal _price;
public decimal Price
{
get => _price;
set => _price = value < 0 ? 0 : value; // Evita preços negativos
}Convenção de Nomenclatura
Backing fields normalmente usam um prefixo de sublinhado (_price) ou letras minúsculas (price) para distingui-los do nome da propriedade.
Auto-Properties vs Backing Fields
Propriedades autoimplementadas como public decimal Price { get; set; } criam automaticamente um backing field oculto. Backing fields explícitos oferecem o mesmo armazenamento com controle total sobre o comportamento.
Experimente você mesmo
using System;
using Sensors;
class Program
{
public static void Main(string[] args)
{
// Ler as entradas
string location = Console.ReadLine();
double initialTemp = Convert.ToDouble(Console.ReadLine());
double updatedTemp = Convert.ToDouble(Console.ReadLine());
// TODO: Criar um TemperatureSensor com a localização e a temperatura inicial
// TODO: Imprimir a localização do sensor e as leituras de temperatura iniciais
// Formato: "Sensor: {Location}"
// Formato: "Temperature: {Temperature}C ({TemperatureFahrenheit}F)"
// TODO: Atualizar a temperatura do sensor com o valor atualizado
// TODO: Imprimir as leituras de temperatura atualizadas
// Formato: "Updated Temperature: {Temperature}C ({TemperatureFahrenheit}F)"
}
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos de POO
Arquivos ExternosNamespaces e DiretivasIntrodução a Classes e ObjetosA Palavra-chave 'this'Métodos e ParâmetrosCampos vs PropriedadesConstrutoresInicializadores de ObjetosRecapitulação - Calculadora Simples4Herança
Sintaxe Básica de Herança (:)A Palavra-chave 'base'Palavras-chave Virtual e OverrideClasses SeladasA Classe Base 'object'Recapitulação - Hierarquia de Funcionários7Recursos Avançados
Sobrecarga de OperadoresIndexadores (this[])Sobrescrita de ToString()Métodos de ExtensãoRecapitulação - Lista Personalizada10Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoSingleton Thread-SafePadrão FactoryPadrão Observer (Eventos)Padrão Strategy2Propriedades e Membros Estáticos
Propriedades AutoimplementadasPropriedades de Apenas Leitura/EscritaCampos e Métodos EstáticosClasses EstáticasMembros com Corpo de Expressão5Polimorfismo e Interfaces
Polimorfismo: Compilação vs ExecuçãoInterface vs Classe AbstrataMúltiplas InterfacesInterfaces ExplícitasUpcasting e DowncastingRecapitulação - Calculadora de Formas8Conceitos Avançados de POO
Composição sobre HerançaGenerics (Classes e Métodos)Delegates e EventosAtributos e ReflectionIDisposable e a Instrução usingFundamentos de Injeção de Dependência11Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão Composite3Arquitetura de Classes
Dados de Instância vs EstáticosPalavras-chave 'readonly' e 'const'Campos de SuporteRecapitulação - Gerenciador de Conta Bancária6Encapsulamento
Modificadores de AcessoPropriedades para EncapsulamentoImplementação de Ocultação de DadosPadrões de ImutabilidadeRecapitulação - Registros de Estudantes9Argumentos Variáveis
A Palavra-chave 'params'Parâmetros OpcionaisArgumentos NomeadosSobrecarga de Métodos