como faço para explicar que, se (xyz == null) os cheques não são “protetor”

StackOverflow https://stackoverflow.com/questions/1647666

  •  22-07-2019
  •  | 
  •  

Pergunta

i ter alguns desenvolvedores que constantemente colocam Se as verificações nulos

Por exemplo:

Run(Order order)
{
  if (order == null) return;
}

em seu código como eles pensam que estão protegendo sua classe se alguém passa em um parâmetro que é nulo. Estou tentando dizer-lhes que a falha na sua lógica, porque se alguém está passando nula neste caso, seu mais provável um problema com o código do consumidor e, em vez desta classe lançar uma exceção e não rápido, ele graciosamente lida com o mau comportamento de o consumidor e manter chugging distância.

Outra sugestão é ter condição ou guarda classe que falhar rápido e lançar exceções. qualquer coisa, mas ignorando o fato de que o consumidor provavelmente tem algum outro problema e eu estou ajuda mascará-lo.

Como faço para obter as pessoas a apreciar o fato de que sua classe não deve ser tão indulgente. se alguém não passar em bons dados, eles devem ser informados.

quaisquer artigos de boa ou sugestões para me ajudar a conseguir este ponto de vista?

Foi útil?

Solução

Se sua classe não pode aceitar argumentos null, então a melhor coisa a fazer é esta:

if (arg == null)
    throw new ArgumentNullException();

Este é muito preferível a obtenção de um NullPointerException mais profunda para baixo da pilha. Na pior das hipóteses, você vai armazenar em cache que em algum lugar null e não vai realmente provocar a exceção até muito mais tarde, e muito divertido ver como você vai ter a depuração do problema então .

E, como os outros, às vezes, o contrato diz que null está bem. Nesse caso, tendo uma cláusula de guarda em torno de algumas partes do código está correto - embora, mesmo assim, eu diria que o melhor design seria adicionar uma sobrecarga sem os argumentos opcionalmente nulos

.

Outras dicas

É realmente depende da situação precisa. Raramente é aconselhável dar sugestões gerais como "verificações nulos não colocar em seu código", como você parece estar indicando. O contrato da classe deve definir o que é legítimo eo que não é. Mas se o contrato deixa claro que passando nulo não é aceitável, em seguida, uma exceção é realmente uma resposta apropriada.

Como todos os outros disseram, é muito preferível a falhar cedo do que para obter problemas misteriosos na produção porque a função não fez nada quando foi esperado para. Se a função retornar para argumentos nulos, como no seu exemplo).

Mesmo que a função não retornar e apenas lança uma NullReferenceException, é eaiser para resolver um bug quando você sabe que um argumento era nulo. Se uma função lança uma NullReferenceException, você não tem idéia do que era null ou quem foi a culpa.

Eu gostaria de acrescentar que ArgumentNullException leva um parâmetro por uma razão.

É melhor escrever

if(myArg == null) throw new ArgumentNullException("myArg");

do que para lançar uma ArgumentNullException sem paramName.

Desta forma, se você tiver uma exceção de uma função que leva cinco parâmetros, você vai saber qual dos parâmetros causou o problema. Isto é especialmente importante se você não pode anexar um depurador. (Por exemplo, em um servidor Web de produção ou uma máquina do usuário final)

Se você estiver escrevendo muitas funções, isso pode ser um monte de sobrecarga, especialmente porque não há nenhuma IntelliSense para as cordas. Eu escrevi um trecho de código para gerar essas verificações:

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
    <CodeSnippet Format="1.0.0">
        <Header>
            <Title>Check for null arguments</Title>
            <Shortcut>tna</Shortcut>
            <Description>Code snippet for throw new ArgumentNullException</Description>
            <Author>SLaks</Author>
            <SnippetTypes>
                <SnippetType>Expansion</SnippetType>
                <SnippetType>SurroundsWith</SnippetType>
            </SnippetTypes>
        </Header>
        <Snippet>
            <Declarations>
                <Literal>
                    <ID>Parameter</ID>
                    <ToolTip>Paremeter to check for null</ToolTip>
                    <Default>value</Default>
                </Literal>
            </Declarations>
            <Code Language="csharp"><![CDATA[if ($Parameter$ == null) throw new ArgumentNullException("$Parameter$");
        $end$]]>
            </Code>
        </Snippet>
    </CodeSnippet>
</CodeSnippets>

contratos de código em .NET 4.0, esperamos tornar este comportamento muito mais consistente. Quaisquer artigos que falam sobre contratos de código ajudarão a idéia do outro lado, e no futuro, este tipo de sintaxe irá fornecer o método.

http : //blogs.msdn.com/bclteam/archive/2008/11/11/introduction-to-code-contracts-melitta-andersen.aspx

Eu não assisti com ele, mas eiffel.com tem 2 apresentações ( corrediças + áudio) sobre o tema da programação por contrato . Esses caras têm inventado o conceito, então se alguém pode explicar isso é eles :-)

Às vezes você não pode dizer às pessoas por que uma prática como isso é errado - eles têm que descobrir isso por si mesmos. Mas você poderia ajudá-los a chegar lá por surgir com algum teste de unidade que causa alguma falha desagradável devido a este problema, e torná-los depurar o erro.

Se especifica contrato do método que os seus argumentos não deve ser nulo, então a coisa certa a fazer é torná-lo explícito, usando um Assert, como este:

Debug.Assert( item != null, "Null items are not supported );

Isto irá falhar rapidamente quando o executável é construído usando uma configuração de depuração, mas vai apresentar de zero a degradação do desempenho quando construído usando uma configuração de lançamento.

Esta parece ser uma pergunta sobre como melhor escrever código que é viável. É minha nova crença de que você deve assumir a ignorância de todos os consumidores de seu código. Eu me meti em encrencas por supondo que eu ou alguém com profundo conhecimento estaria consumindo meu código. A única coisa que eu gostaria de acrescentar a lançar uma exceção é a criação de exceções personalizadas, bem como deixando migalhas de pão na exceção interna. Eu acredito fortemente em dar seus desenvolvedores a chance de correr para baixo a questão especialmente se for devido a dados. Passo a maior parte do meu tempo a olhar para os dados que quebra o meu código e se você pode deixar dicas você vai economizar semanas em um ano.

Bem, antes de tudo, você é inequivocamente incorreta. Você está abraçando uma falácia lógica muito sério. Você quer que seu código seja correta em virtude do código assumindo que tudo o que acontece em torno dele está correta. Como se a correção foi algum tipo de pó de pirlimpimpim mágico que você só precisa para pulverizar em todos os lugares.

Todos os erros são ou parecer estúpido, uma vez que estão expostos. Mas suas verificações como este que lhes destrinchar a expor-se. Até então, os erros são invisíveis. E para projetos grandes e complexos o suficiente, você não sabe o que vai encontrar o bug ou sob que condições eles serão encontrados. Código que é projetada para a resiliência normalmente tem cheques como este em todo o lugar e também verificar os valores de retorno para cada função que tem que incluir valores de erro. Então você acaba que codifica uma "Eu não posso fazer isso porque as subfunções I dependem não estão funcionando" semântica que é realmente tratada adequadamente. O grande valor deste é que geralmente você pode implementar arounds de trabalho ou instrumentação de depuração auto-conhecimento com bastante facilidade. Por que você quer fazer coisas como isso é porque a maioria dos erros difíceis geralmente contam com ambas as propriedades para depurar corretamente.

Saiba algumas lições de seus desenvolvedores. Eles colocaram cheques como aquele lá, porque eles não sabem por que às vezes eles ficam estranhos resultados de funções. Você chamá-los de ingênuos ou excessivamente cautelosa por causa de um pedaço estreito de conhecimento que você tem que eles não fazem. Mas quando você está depurando algo desagradável você vai se perguntar por que você não tem esses controlos no seu código, e você vai acabar parecendo tão ingênuo por não ser capaz de detectar o erro no primeiro lugar.

Em resumo:. Nenhum código é feita robusta assumindo robustez sobre o ambiente ao seu redor

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top