Eu sempre soube que as propriedades (ou seja, suas operações de set / get) deveriam ser rápidas / imediatas e sem falhas. Você nunca deve tentar pegar ou configurar uma propriedade.
Mas estou procurando algumas maneiras de aplicar a segurança baseada em função nas propriedades de alguns objetos. Por exemplo, uma propriedade Employee.Salary. Algumas das soluções que encontrei e outras que tentaram (uma em particular é o exemplo da AOP aqui ) envolvem lançar uma exceção se o acessador não tiver as permissões corretas - mas isso vai contra uma regra pessoal que eu tive por um longo tempo agora.
Então eu pergunto: estou errado? As coisas mudaram? Foi aceito que as propriedades possam gerar exceções?
.net
exceptions
Steven Evers
fonte
fonte
Respostas:
quando você define o valor de uma propriedade, é possível lançar uma exceção em um valor inválido
obter o valor de uma propriedade (quase) nunca deve gerar uma exceção
para acesso baseado em função, use interfaces / fachadas diferentes / mais burras; não deixe as pessoas verem coisas que não podem ter!
fonte
Considero que a maioria está em má forma, mas até a Microsoft recomenda o uso de exceções às vezes. Um bom exemplo é a propriedade abstrata Stream.Length . Conforme as diretrizes, eu estaria mais preocupado em evitar efeitos colaterais em getters e limitar efeitos colaterais em setters.
fonte
Definitivamente, eu argumentaria que há uma falha no design se você sentir a necessidade de lançar exceções de um criador de propriedades ou um criador de propriedades.
Uma propriedade é uma abstração que representa algo que é apenas um valor . E você deve poder definir um valor sem temer que isso possa gerar uma exceção. *
Se definir a propriedade resultar em um efeito colateral, isso realmente deve ser implementado como um método. E se não produzir efeitos colaterais, nenhuma exceção deve ser lançada.
Um exemplo já mencionado em uma resposta diferente é a
Stream.Position
propriedade Isso produz efeitos colaterais e pode gerar exceções. Mas esse configurador de propriedades é basicamente apenas um invólucroStream.Seek
que você poderia chamar.Pessoalmente, acredito que a posição não deveria ter sido uma propriedade gravável.
Outro exemplo em que você pode ser tentado a lançar uma exceção de um configurador de propriedades está na validação de dados:
Mas existe uma solução melhor para esse problema. Introduza um tipo representando um endereço de email válido:
A
Email
classe garante que não possa conter um valor que não seja um endereço de email válido, e as classes que precisam armazenar emails ficam isentas do dever de validá-las.Isso também leva a uma maior coesão (um indicador de bom design de software) - o conhecimento sobre o que é um endereço de e-mail e como é validado existe apenas no
Email
classe, que tem apenas essa preocupação.* ObjectDisposedException é a única exceção válida (sem trocadilhos) que posso pensar no momento.
fonte
Sei que sua pergunta é específica ao .NET , mas como o C # compartilha um pouco da história com Java, pensei que você poderia estar interessado. Estou não de qualquer maneira o que implica que porque algo é feito em Java, isso deve ser feito em C #. Eu sei que os dois são muito diferentes, especialmente em como o C # tem um suporte de propriedades de linguagem muito aprimorado. Estou apenas dando algum contexto e perspectiva.
Na especificação JavaBeans :
Leve tudo isso com um grão de sal, por favor. A especificação do JavaBeans é antiga e as Propriedades do C # são (IMO) uma grande melhoria em relação às propriedades baseadas em "convenção de nomenclatura" que o Java possui. Eu só estou tentando dar um pouco de contexto, é tudo!
fonte
O ponto de uma propriedade é o Princípio de Acesso Uniforme , ou seja, que um valor deve ser acessível através da mesma interface, implementada por armazenamento ou computação. Se sua propriedade está lançando uma exceção que representa uma condição de erro além do controle do programador, do tipo que deve ser capturado e manipulado, você está forçando seu cliente a saber que o valor é obtido via computação.
Por outro lado, não vejo nenhum problema em usar afirmações ou exceções semelhantes a afirmações que visam sinalizar o uso incorreto da API ao programador em vez de ser capturado e manipulado. Nesses casos, a resposta correta da perspectiva do usuário da API não é lidar com a exceção (importando-se assim implicitamente com a obtenção do valor por meio de computação ou armazenamento). É para corrigir seu código para que o objeto não termine em um estado inválido ou faça com que você corrija seu código para que a afirmação não seja acionada.
fonte
AFAIK, essa orientação vem principalmente do processo de pensamento de que as propriedades podem acabar sendo usadas no tempo de design . (Por exemplo, a propriedade Text em um TextBox) Se a propriedade lançar uma exceção quando um designer estiver tentando acessá-lo, o VS não terá um bom dia. Você receberá vários erros ao tentar usar o designer e, para os designers da interface do usuário, eles não serão renderizados. Também se aplica ao tempo de depuração, embora o que você verá em um cenário de exceção seja apenas "xxx Exception" e não atrapalhe o VS IIRC.
Para os POCOs, isso realmente não fará nenhum mal, mas eu ainda evito fazer isso sozinho. Eu acho que as pessoas vão querer acessar propriedades com mais frequência, então normalmente devem ter um custo baixo. As propriedades não devem executar o trabalho dos métodos, devem apenas obter / definir algumas informações e concluir com elas como regra geral.
fonte
Embora muito dependa do contexto, eu geralmente evitaria colocar qualquer tipo de lógica quebrável (incluindo exceções) nas propriedades. Apenas como um exemplo, há muitas coisas que você (ou alguma biblioteca que você está usando) poderia fazer que usam reflexão para iterar sobre propriedades, resultando em erros que você não esperava no tempo de design.
Digo geralmente, embora possa haver momentos em que você absolutamente, definitivamente, deseja bloquear algo sem se preocupar muito com as consequências. Segurança, eu acho que seria o caso clássico lá.
fonte