Estou fazendo um curso de C # agora e estou tentando descobrir a melhor maneira de fazer as coisas. Eu venho de uma experiência em Java e, portanto, estou familiarizado apenas com as melhores práticas de Java; Sou um novato em C #!
Em Java, se tenho uma propriedade privada, faço isso;
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
Em C #, vejo que existem muitas maneiras de fazer isso.
Posso fazer como Java:
private string name;
public void setName(string name) {
this.name = name;
}
public string getName() {
return this.name;
}
Ou posso fazer desta forma:
private string name;
public string Name {
get { return name; }
set { name = value; }
}
Ou:
public string Name { get; set; }
Qual devo usar e quais são as advertências ou sutilezas envolvidas em cada abordagem? Ao criar classes, estou seguindo as melhores práticas gerais que conheço de Java (especialmente lendo Effective Java). Então, por exemplo, estou favorecendo a imutabilidade (fornecendo setters apenas quando necessário). Estou apenas curioso para ver como essas práticas se encaixam nas várias maneiras de fornecer setters e getters em C #; essencialmente, como traduziria as práticas recomendadas do mundo Java para C #?
EDITAR
Eu estava postando isso como um comentário à resposta de Jon Skeet, mas depois demorou muito:
Que tal uma propriedade não trivial (ou seja, com processamento e validação significativos, talvez)? Eu ainda poderia expô-lo por meio de uma propriedade pública, mas com a lógica encapsulada em get
e set
? Por que eu faria / deveria fazer isso sobre ter métodos setter e getter dedicados (com processamento associado e lógica de validação).
fonte
public int Y { get; } = y;
).Se você só precisa de uma variável para armazenar alguns dados:
Quer fazer com que pareça somente leitura?
Ou melhor ainda ...
Quer fazer alguma verificação de valor antes de atribuir a propriedade?
Em geral, GetXyz () e SetXyz () são usados apenas em certos casos, e você só precisa usar sua intuição quando achar que está certo. Em geral, eu diria que espero que a maioria das propriedades get / set não contenha muita lógica e tenha poucos, se houver, efeitos colaterais inesperados. Se a leitura de um valor de propriedade requer a chamada de um serviço ou a obtenção de entrada de um usuário para construir o objeto que estou solicitando, eu o envolveria em um método e o chamaria de algo como
BuildXyz()
, em vez deGetXyz()
.fonte
myList.Add()
, por exemplo (desde que o objeto seja exposto a mudanças, ele é mutável).Min
/Max
. Você quer garantir issoMax > Min
? Ter umSetRange(Min, Max)
pode fazer sentido, mas como você vai ler esses valores de volta? Propriedades mínimas / máximas somente leitura? Lançar exceções para entrada inválida parece ser a maneira mais limpa de lidar com isso.Use propriedades em C #, não métodos get / set. Eles estão aí para sua conveniência e isso é idiomático.
Quanto aos seus dois exemplos de C #, um é simplesmente açúcar sintático para o outro. Use a propriedade auto se tudo que você precisar for um invólucro simples em torno de uma variável de instância, use a versão completa quando precisar adicionar lógica no getter e / ou setter.
fonte
Em C #, favorece as propriedades para expor campos privados para get e / ou set. A forma que você mencionou é uma propriedade autônoma em que get e set geram automaticamente um campo de suporte de pivô oculto para você.
Eu prefiro propriedades automáticas quando possível, mas você nunca deve fazer um par de métodos set / get em C #.
fonte
Esta é simplesmente uma propriedade implementada automaticamente e é tecnicamente igual a uma propriedade normal. Um campo de apoio será criado durante a compilação.
Todas as propriedades são eventualmente convertidas em funções, portanto, a implementação real compilada no final é a mesma que você está acostumado em Java.
Use as propriedades implementadas automaticamente quando não precisar fazer operações específicas no campo de apoio. Caso contrário, use uma propriedade comum. Use as funções get e set quando a operação tiver efeitos colaterais ou for computacionalmente cara; caso contrário, use as propriedades.
fonte
Independentemente de qual forma você escolher em C #, o resultado final é o mesmo. Você obterá uma variável backinng com métodos getter e setter separados. Ao usar propriedades, você está seguindo as práticas recomendadas e, portanto, é uma questão de quão detalhado você deseja obter.
Pessoalmente, eu escolheria propriedades automáticas, a última versão:,
public string Name { get; set; }
uma vez que ocupam menos espaço. E você sempre pode expandi-los no futuro se precisar adicionar algo como validação.fonte
Sempre que possível, prefiro o público
string Name { get; set; }
porque é conciso e de fácil leitura. No entanto, pode haver momentos em que este seja necessáriofonte
Em C #, a forma preferida é por meio de propriedades em vez de métodos
getX()
esetX()
. Além disso, observe que o C # não requer que as propriedades tenham get e set - você pode ter propriedades get-only e propriedades set-only.fonte
Primeiro, deixe-me tentar explicar o que você escreveu:
Esta estrutura também é usada hoje em dia, mas é mais adequada se você quiser fazer alguma funcionalidade extra, por exemplo, quando um valor é definido, você pode analisá-lo para capitalizá-lo e salvá-lo em membro privado para alterar o uso interno.
Com .net framework 3.0
Desejo-lhe melhor sorte em C #
fonte
Conforme mencionado, todas essas abordagens resultam no mesmo resultado. O mais importante é que você escolha uma convenção e a siga. Prefiro usar os dois últimos exemplos de propriedades.
fonte
como a maioria das respostas aqui, use as propriedades Automáticas. Intuitivo, menos linhas de código e mais limpo. Se você deve serializar sua classe, marque a classe
[Serializable]
/ com o[DataConract]
atributo. E se você estiver usando,[DataContract]
marque o membro comO setter privado ou público depende da sua preferência.
Observe também que as propriedades automáticas requerem getters e setters (públicos ou privados).
Alternativamente, se você deseja apenas obter / definir, crie você mesmo um campo de apoio
fonte
Ao usar propriedades, há uma advertência que ainda não foi mencionada: com propriedades, você não pode ter nenhuma parametrização de seus getters ou setters.
Por exemplo, imagine que você deseja recuperar os itens de uma lista e também aplicar um filtro ao mesmo tempo. Com um método get, você pode escrever algo como:
Em contraste, com uma propriedade, você é forçado a primeiro devolver todos os itens
e, em seguida, aplique o filtro na próxima etapa ou você terá que adicionar propriedades dedicadas que expõem itens filtrados por critérios diferentes, o que logo sobrecarrega sua API:
O que às vezes pode ser um incômodo é quando você começou com uma propriedade, por exemplo,
obj.items
e depois descobriu que a parametrização getter ou setter é necessária ou tornaria as coisas mais fáceis para o usuário da API de classe. Agora você precisaria reescrever sua API e modificar todos os locais em seu código que acessam essa propriedade ou encontrar uma solução alternativa. Em contraste, com um método get, por exemploobj.getItems()
, você pode simplesmente estender a assinatura do seu método para aceitar um objeto de "configuração" opcional, por exemplo,obj.getItems(options)
sem ter que reescrever todos aqueles lugares que chamam seu método.Dito isso, as propriedades (auto-implementadas) em C # ainda são atalhos muito úteis (pelas várias razões mencionadas aqui), já que na maioria das vezes a parametrização pode não ser necessária - mas esta advertência permanece.
fonte