Acabei de perceber que a construção da propriedade C # também pode ser usada com um modificador de acesso privado :
private string Password { get; set; }
Embora isso seja tecnicamente interessante, não consigo imaginar quando o usaria, pois um campo privado envolve ainda menos cerimônia :
private string _password;
e não consigo imaginar quando precisaria obter internamente, mas não definir ou definir, mas não obter um campo privado:
private string Password { get; }
ou
private string Password { set; }
mas talvez exista um caso de uso com classes aninhadas / herdadas ou talvez um get / set possa conter lógica em vez de apenas devolver o valor da propriedade, embora eu tenderia a manter as propriedades estritamente simples e permitir que métodos explícitos fizessem qualquer lógica, por exemplo GetEncodedPassword()
.
Alguém usa propriedades privadas em C # por qualquer motivo ou é apenas uma daquelas construções tecnicamente possíveis, embora raramente usadas em código real?
Termo aditivo
Boas respostas, lendo-as, selecionei esses usos para propriedades particulares:
- quando campos particulares precisam ser carregados lentamente
- quando campos particulares precisam de lógica extra ou são valores calculados
- pois os campos particulares podem ser difíceis de depurar
- para "apresentar um contrato a si mesmo"
- converter / simplificar internamente uma propriedade exposta como parte da serialização
- agrupando variáveis globais para serem usadas dentro da sua classe
fonte
Respostas:
Eu os uso se precisar armazenar em cache um valor e quiser carregá-lo com preguiça.
fonte
return _password ?? (_password = CallExpensiveOperation());
return _password ?? (_password = CallExpensiveOperation());
há algum tempo. Ou, na verdade, o Resharper prefere :).private string Password => _password ?? (_password = CallExpensiveOperation());
private string Password => _password ??= CallExpensiveOperation();
CallExpensiveOperation();
é chamado durante a construção / inicialização do objeto que contém e não quando a propriedade é acessada pela primeira vez.O principal uso disso no meu código é a inicialização lenta, como outros já mencionaram.
Outro motivo para propriedades privadas sobre campos é que as propriedades privadas são muito, muito mais fáceis de depurar do que os campos privados. Frequentemente, quero saber coisas como "esse campo está sendo configurado inesperadamente; quem é o primeiro chamador que define esse campo?" e é muito mais fácil se você simplesmente colocar um ponto de interrupção no levantador e pressionar ir. Você pode colocar o login lá. Você pode colocar métricas de desempenho lá. Você pode colocar verificações de consistência que são executadas na compilação de depuração.
Basicamente, tudo se resume a: código é muito mais poderoso que dados . Qualquer técnica que me permita escrever o código necessário é boa. Os campos não permitem que você escreva código neles, as propriedades fazem.
fonte
Eu pessoalmente uso isso mesmo quando não preciso de lógica no getter ou setter de uma propriedade. O uso de uma propriedade, mesmo privada, ajuda a proteger seu código para o futuro, para que você possa adicionar a lógica a um getter posteriormente, se necessário.
Se eu achar que uma propriedade pode eventualmente exigir lógica extra, algumas vezes a agruparei em uma propriedade privada em vez de usar um campo, apenas para não precisar alterar meu código posteriormente.
Em um caso semi-relacionado (embora diferente da sua pergunta), eu frequentemente uso os setters privados em propriedades públicas:
Isso fornece a você um getter público, mas mantém o setter privado.
fonte
Um bom uso para obter propriedades privadas apenas são os valores calculados. Várias vezes tive propriedades que são privadas somente de leitura e apenas fazem um cálculo sobre outros campos no meu tipo. Não é digno de um método e não é interessante para outras classes, portanto é propriedade privada.
fonte
A inicialização lenta é um local onde elas podem ser organizadas, por exemplo
Depois, você pode escrever: em
this.MyType
todo lugar, em vez de,this.mytype.Value
e encapsular o fato de que ele é instanciado preguiçosamente em um único local.Uma coisa que é uma vergonha é que o C # não suporta o escopo do campo de suporte da propriedade (ou seja, declarando-o dentro da definição da propriedade) para ocultá-lo completamente e garantir que ele possa ser acessado apenas através da propriedade.
fonte
field-declaration
o escopo do escopoaccessor-declarations
está classificado como número 1 na minha lista de desejos em C # há muito tempo. Se você conseguir que isso seja projetado e implementado em alguma versão futura (real), vou fazer um bolo para você.O único uso que eu consigo pensar
fonte
private bool IsPasswordSet() { return !String.IsNullOrEmpty(_password); }
Propriedades e campos não são um para um. Uma propriedade é sobre a interface de uma classe (seja sobre sua interface pública ou interna), enquanto um campo é sobre a implementação da classe. As propriedades não devem ser vistas como uma maneira de expor apenas os campos; elas devem ser vistas como uma maneira de expor a intenção e o objetivo da classe.
Assim como você usa propriedades para apresentar um contrato a seus consumidores sobre o que constitui sua classe, você também pode apresentar um contrato a si mesmo por razões muito semelhantes. Então, sim, eu uso propriedades privadas quando faz sentido. Às vezes, uma propriedade privada pode ocultar detalhes de implementação, como carregamento lento, o fato de que uma propriedade é realmente um conglomerado de vários campos e aspectos, ou que uma propriedade precisa ser virtualmente instanciada a cada chamada (pense
DateTime.Now
). Definitivamente, há momentos em que faz sentido impor isso mesmo a você mesmo no back-end da classe.fonte
Eu os uso em serialização, com coisas como
DataContractSerializer
ou protobuf-net que suportam esse uso (XmlSerializer
não). É útil se você precisar simplificar um objeto como parte da serialização:fonte
Uma coisa que faço o tempo todo é armazenar variáveis "globais" / cache no
HttpContext.Current
fonte
Eu os uso de vez em quando. Eles podem facilitar a depuração de itens quando você pode colocar facilmente um ponto de interrupção na propriedade ou adicionar uma instrução de log etc.
Também pode ser útil se você precisar alterar posteriormente o tipo de dados de alguma forma ou se precisar usar reflexão.
fonte
Uso propriedades privadas para reduzir o código para acessar subpropriedades que costumam ser usadas.
É útil se houver muitas subpropriedades.
fonte
É uma prática comum modificar apenas membros com métodos get / set, mesmo privados. Agora, a lógica por trás disso é que você saiba que seu get / set sempre se comporta de uma maneira específica (por exemplo, disparando eventos) que não parece fazer sentido, pois esses não serão incluídos no esquema de propriedades ... mas velhos hábitos morrem com força.
fonte
Faz todo o sentido quando existe uma lógica associada ao conjunto de propriedades ou get (pense na inicialização lenta) e a propriedade é usada em alguns lugares da classe.
Se é apenas um campo de apoio direto? Nada vem à mente como uma boa razão.
fonte
Eu sei que esta pergunta é muito antiga, mas as informações abaixo não estavam em nenhuma das respostas atuais.
Se você estiver injetando suas dependências, poderá ter um Getter em uma propriedade e não um setter, pois isso indicaria uma propriedade somente leitura. Em outras palavras, a propriedade pode ser definida apenas no construtor e não pode ser alterada por nenhum outro código da classe.
O Visual Studio Professional também fornecerá informações sobre uma propriedade e não sobre um campo, facilitando a visualização do que seu campo está sendo usado.
fonte
Bem, como ninguém mencionou, você pode usá-lo para validar dados ou bloquear variáveis.
Validação
Travamento
Nota: Ao bloquear uma referência, você não bloqueia o acesso aos membros do objeto referenciado.
Referência preguiçosa: Quando o carregamento é lento, você pode precisar assiná- lo de forma assíncrona, para a qual atualmente existe o AsyncLazy . Se você estiver em versões anteriores ao Visual Studio SDK 2015 ou não o estiver usando, também poderá usar o AsyncLazy do AsyncEx .
fonte
Alguns usos mais exóticos de campos explícitos incluem:
ref
ouout
com o valor - talvez porque seja umInterlocked
contadorstruct
layout explícito (talvez para mapear para um despejo de C ++, ouunsafe
código em )BinaryFormatter
o tratamento automático de campos (alterar para adereços automáticos altera os nomes e, portanto, interrompe o serializador)fonte