Há momentos em que precisarei modificar um valor passado para um método de dentro do próprio método. Um exemplo seria desinfetar uma string como este método aqui:
void SanitizeName(string Name)
{
Name = Name.ToUpper();
//now do something here with name
}
Isso é puramente inofensivo, pois o Name
argumento não está sendo transmitido por referência. No entanto, se, por algum motivo, um desenvolvedor decidir no futuro passar todos os valores por ref, qualquer higienização da string afetará o valor fora do método, o que pode ter resultados negativos.
Portanto, em vez de reatribuir ao próprio argumento, eu sempre crio uma cópia local assim:
void SanitizeName(string Name)
{
var SanitizedName = Name.ToUpper();
//now do something here with name
}
Isso garante que a alteração do valor transmitido nunca afetará o andamento fora do método, mas estou me perguntando se estou sendo excessivamente paranóico sobre isso.
design
programming-practices
oscilatingcretin
fonte
fonte
Name = Name.ToUpper();
torna o código mais difícil de seguir em sua mente conforme o valor dasName
alterações. Seu segundo exemplo não é apenas mais à prova de futuro, é mais fácil entender o que está fazendo.if (param == NULL) param = default_value;
?by ref
que não foi aprovado de maneira antecipada e, portanto, convertendo o acesso local em um acesso não local por algum motivo, ele sempre deve verificar as consequências com cuidado.Respostas:
Eu acho que depende das suas convenções de codificação no seu projeto.
Pessoalmente, deixei o eclipse adicionar automaticamente a
final
palavra-chave a todas as variáveis e parâmetros. Dessa forma, você vê à primeira vista se um parâmetro é reutilizado.No projeto em meu trabalho, não recomendamos a reutilização de parâmetros, mas se você quiser chamar, por exemplo,
.trim()
ou definir um padrão em umnull
caso, reutilizamos o parâmetro na maioria das vezes, porque a introdução de uma nova variável é, nesses casos, menos legível do que a reutilização do parâmetro.Você realmente não deve reutilizar um parâmetro para armazenar um conteúdo muito diferente porque o nome não se refere mais ao seu conteúdo. Mas isso é verdade para toda reatribuição de uma variável e não restrito a parâmetros.
Portanto, reúna-se com sua equipe e formule convenções de codificação que abordam esse assunto.
fonte
Se você usar um analisador de código estático para fins de segurança, ele poderá ficar confuso e você achar que não validou ou higienizou a variável de parâmetro de entrada antes do uso. Se você usar
Name
uma consulta SQL, por exemplo, ela poderá reivindicar uma vulnerabilidade de injeção SQL, o que custaria um tempo para explicar. Isso é mau. Por outro lado, o uso de uma variável com nome distinto para a entrada higienizada, sem realmente higienizar a entrada, é uma maneira rápida de silenciar os analisadores de código ingênuos (descoberta de vulnerabilidade negativa falsa).fonte
A resposta para isso depende 100% de quem vai ler seu código. Quais estilos eles acham mais úteis?
Eu descobri que o caso mais geral é que evita-se reatribuir valores a argumentos de função, porque muitos desenvolvedores têm modelos mentais de como funciona a chamada de função, assumindo que você nunca faz isso. Esse problema pode ser agravado por depuradores que imprimem os valores dos argumentos com os quais você chama cada função. Tecnicamente , essas informações não estão corretas se você editar os argumentos e isso pode levar a algumas frustrações estranhas.
Dito isto, os modelos mentais mudam. Em seu ambiente de desenvolvimento específico, pode ser desejável ter
name
"a melhor representação do nome neste momento". Pode ser desejável vincular mais explicitamente as variáveis nas quais você está trabalhando aos argumentos deles, mesmo que você tenha feito algumas modificações nos valores deles ao longo do caminho. Pode até haver vantagens substanciais em tempo de execução para reutilizar algumas variáveis específicas, em vez de criar objetos mais volumosos. Afinal, quando você trabalha com sequências de 4 GB, é bom minimizar o número de cópias extras que você precisa fazer!fonte
Eu tenho um problema completamente diferente com seu exemplo de código:
O nome do seu método é
SanitizeName
. Nesse caso, espero que ele desinfete um nome ; porque isto é, o que você diz ao leitor sobre sua função.A única coisa que você deve executar é desinfetar um determinado nome . Sem ler seu código, eu esperaria o seguinte:
Mas você implica que seu método faz um pouco mais do que apenas higienizar. Esse é um cheiro de código e deve ser evitado.
Sua pergunta não é sobre: É uma má prática reutilizar os parâmetros do método? É mais: os efeitos colaterais e o comportamento não esperado são más práticas?
A resposta para isso é clara: sim!
Você engana seu leitor ao não retornar nada. O nome do método indica claramente que você está fazendo algo
Name
. Então, para onde deve ir o resultado? Pela sua função, a assinaturavoid
lê: eu uso,Name
mas não prejudico o id, nem falo sobre o resultado (explicitamente). Talvez haja uma exceção lançada, talvez não; masName
não é alterado . Essa é a semântica oposta ao nome do seu método.O problema é menos a reutilização do que os efeitos colaterais . Para evitar efeitos colaterais , não reutilize uma variável. Se você não tiver efeitos colaterais, não há problema.
fonte