C#3.0 Propriedades automáticas, por que não acessar o campo diretamente?
-
05-07-2019 - |
Pergunta
Com a nova abordagem de ter o GET/Set dentro do atribuições da classe como essa:
public string FirstName {
get; set;
}
Por que simplesmente não simplesmente colocar o atributo em primeiro lugar sem acessador?
Solução
Dois dos grandes problemas com acesso direto à variável interna da classe (campo/atributo) são:
1) Você não pode facilmente banco de dados contra campos.
2) Se você expõe os campos públicos de suas classes, mais tarde não poderá alterá -las para propriedades (por exemplo: para adicionar a lógica de validação aos setters)
Outras dicas
Porque, no futuro, se você alterar a implementação, o código usando a interface atual não será interrompido.
Por exemplo, você implementa uma classe simples com um campo público e começa a usar sua classe em alguns módulos externos. Um mês depois, você descobre que precisa implementar o carregamento preguiçoso nessa classe. Você precisaria transformar o campo em uma propriedade. Do ponto de módulo externo do Ciew, ele pode parecer a mesma sintaxical, mas não é. Uma propriedade é um conjunto de funções, enquanto um campo é um deslocamento em uma instância de classe.
Ao usar uma propriedade, você reduz efetivamente o risco que a interface mudará.
Isso se resume principalmente a isso, tendo se tornado uma convenção de codificação comum. Isso facilita adicionar o código de processamento personalizado, se desejar. Mas você está correto, tecnicamente não há necessidade real disso. No entanto, se você adicionar processamento personalizado posteriormente, isso o ajudará a não quebrar a interface.
Esse estilo de notação é mais útil quando você mistura a acessibilidade para o getter e o setter. Por exemplo, você pode escrever:
public int Foo { get; private set; }
Você também pode colocar um setter interno ou até tornar o getter privado e o público público.
Essa notação evita a necessidade de escrever explicitamente uma variável privada apenas para lidar com o problema clássico do valor interno e legível interno/externamente.
A chave é que o compilador traduz a propriedade 'Under the Hood' em um par de funções e, quando você tem código que parece estar usando a propriedade, ele está realmente chamando funções quando compilado até a IL.
Então, digamos que você construa isso como um campo e tenha código em uma montagem separada que usa esse campo. Se posteriormente, nas alterações da implementação e você decidir torná-lo uma propriedade para ocultar as alterações do restante do seu código, você ainda precisa recilomar e implantar novamente a outra montagem. Se for uma propriedade desde o início, as coisas funcionarão.
Eu acho que o questionador está perguntando por que não fazer o seguinte ...
public string FirstName { }
Por que se preocupar com os acessores quando você pode encurtá -lo para o acima. Eu acho que a resposta é que, ao exigir que os acessores o torne óbvio para a pessoa que está lendo o código de que é um conjunto/conjunto padrão. Sem eles, você pode ver acima, é difícil identificar que isso está sendo implementado automaticamente.
Quando você recebe um bug e precisa descobrir quais métodos estão modificando seus campos e quando, você se importará muito mais. Colocar acessórios de propriedade leve na frente salva uma quantidade fenomenal de mágoa, caso surja um bug envolvendo o campo que você embrulhou. Eu estive nessa situação algumas vezes e não é agradável, especialmente quando se passa relacionado à reentrância.
Fazer esse trabalho antecipadamente e colocar um ponto de interrupção em um acessador é muito mais fácil do que as alternativas.
Para 99% dos casos, expor um campo público é bom.
O conselho comum é usar os campos: "Se você expõe os campos públicos de suas aulas, mais tarde não poderá alterá -las para propriedades". Sei que todos queremos que nosso código seja à prova de futuro, mas há alguns problemas com esse pensamento:
Os consumidores da sua classe provavelmente podem recompilar quando você muda sua interface.
99% dos membros de seus dados nunca precisarão se tornar propriedades não triviais. Isso é generalidade especulativa. Você está escrevendo muito código que provavelmente nunca será útil.
Se você precisar de compatibilidade binária entre as versões, tornar os membros de dados em propriedades provavelmente não é suficiente. No mínimo, você deve expor apenas interfacess e ocultar todos os construtores e expor as fábricas (veja o código abaixo).
public class MyClass : IMyClass
{
public static IMyClass New(...)
{
return new MyClass(...);
}
}
É um problema difícil, tentando criar código que funcione em um futuro incerto. Muito difícil.
Alguém tem um exemplo de tempo ao usar propriedades triviais salvou seu bacon?
Ele preserva o encapsulamento do objeto e reduz o código para ser mais simples de ler.