Vejo perguntas semelhantes a essa com relação aos nomes de parâmetros que correspondem às propriedades da classe, mas não consigo encontrar nada sobre o uso de um nome de parâmetro igual ao nome do tipo de parâmetro, exceto por maiúsculas e minúsculas em C #. Não parece ser uma violação que eu possa encontrar, mas é considerada uma má prática? Por exemplo, eu tenho o seguinte método
public Range PadRange(Range range) {}
Esse método assume um intervalo e retorna um novo intervalo que teve algum preenchimento aplicado. Portanto, dado o contexto genérico, não consigo pensar em um nome mais descritivo para o parâmetro. No entanto, lembro-me de uma dica que recebi ao ler o código completo sobre "distância psicológica". Diz
A distância psicológica pode ser definida como a facilidade com que dois itens podem ser diferenciados ... Ao depurar, esteja preparado para os problemas causados pela distância psicológica insuficiente entre nomes de variáveis semelhantes e entre nomes de rotina semelhantes. Ao criar o código, escolha nomes com grandes diferenças para evitar o problema.
Minha assinatura de método tem muito "Range" acontecendo, então parece que pode ser um problema com relação a essa distância psicológica. Agora, vejo muitos desenvolvedores fazendo o seguinte
public Range PadRange(Range myRange) {}
Pessoalmente, tenho um forte desagrado por esta convenção. A adição de um prefixo "my" aos nomes de variáveis não fornece contexto adicional.
Eu também vejo o seguinte
public Range PadRange(Range rangeToPad) {}
Gosto disso melhor do que o prefixo "my", mas ainda não me importo com isso no geral. Parece-me excessivamente detalhado e lê desajeitadamente como um nome de variável. Para mim, entende-se que o intervalo será preenchido por causa do nome do método.
Então, com tudo isso exposto, meu instinto é ir com a primeira assinatura. Para mim, está limpo. Não há necessidade de forçar o contexto quando não é necessário. Mas estou prestando um desserviço a mim ou a futuros desenvolvedores com esta convenção? Estou violando uma prática recomendada?
fonte
Range range
bem.Range r
(pelo menos para um corpo de método curto) eRange toPad
.Respostas:
Não pense demais, tudo
Range range
bem. Uso esse tipo de nomeação há mais de 15 anos em C # e provavelmente muito mais em C ++, e nunca tive nenhuma desvantagem real com isso, muito pelo contrário.Obviamente, quando você tem variáveis locais diferentes no mesmo escopo, do mesmo tipo, provavelmente ajudará a investir algum esforço mental para distingui-las adequadamente.
fonte
Wack(Bozo bozoToBeWacked)
um exemplo de redundância no nome da variável que é amplamente expressa pelo próprio método (e, portanto, indesejável pela pergunta original).Wack(Person bozo)
é mais semanticamente valioso, no entanto, pois implica que se espera que apenas bozos sejam malucos.initialRange
. Ainda é muito genérico, mas não tem quase o mesmo nível de aversão quemyRange
.Punch(Bozo punchingBozo, Bozo bozoToBePunched)
. A nomeação detalhada é mais relevante quando você precisa distinguir entre várias coisas (que são semanticamente descritas com praticamente as mesmas palavras). A sugestão de OPRange rangeToPad
não é necessária em seu exemplo de método de parâmetro único, mas pode ser incrivelmente necessária para um método que aceita váriosRange
objetos.Punch(Bozo source, Bozo target)
faria o trabalho #Eu faço isso o tempo todo, isso está me dando uma grande tranqüilidade. Se for um argumento passado para um construtor que precisa ser atribuído a um membro, meu membro também será chamado de intervalo e a atribuição será
E eu normalmente teria uma propriedade chamada Range.
Eles são todos iguais, diferindo apenas no contexto; portanto, faz sentido manter um único nome e você precisará lembrar apenas um nome. Uma coisa é que as diferenças são puramente técnicas.
Você deve ser rigoroso com membros totalmente qualificados com "isso". embora, mas é para isso que serve o StyleCop.
Nota lateral do StyleCop
Controvérsia garantida!
Para aqueles que advogam contra o uso de "isto": eu vi _, m, m_ e apenas nada. A própria linguagem está nos oferecendo uma maneira perfeitamente clara e inequívoca de reconhecimento universal de indicar que estamos lidando com um aluno. Por que diabos você gostaria de criar seu próprio caminho que mutila nomes já perfeitos?
A única razão pela qual consigo pensar que é um hábito herdado da era C, quando realmente fazia sentido fazê-lo, porque não havia outro caminho.
"São mais personagens!" A sério? "O tempo de compilação disparará!" A sério? "Terei que levantar meu mindinho ao digitá-lo!". Como se o tempo de digitação tivesse algum significado no tempo total de desenvolvimento.
Reconheço que qualquer estilo diferente do que você está acostumado suscitará alguma oposição. Mas usar isso de forma consistente é difícil de argumentar. Eis como funciona para mim: Antes de enviar um novo arquivo de código, eu corro o StyleCop e ele encontrará vários membros sem os qualificadores "this". Eu coloquei "isso". na área de transferência, execute pelos membros e insira. Nenhum esforço.
O StyleCop faz muito mais que isso (haha). Existem muitas maneiras pelas quais um desenvolvedor pode (considerando apenas a formatação do código) frustrar o trabalho de manutenção de seu sucessor. StyleCop impede a maioria deles. É inestimável.
Se você é novo: normalmente faz você se queixar por uma semana ou duas e então você vai adorar.
fonte
this
exceto quando essencial. Caso contrário, é apenas barulho. Use_range
para o campo ethis
nunca é necessário, exceto nos métodos de extensão._
é preferível ao ruído dethis.
? Eu diria que um tem um significado imposto pelo idioma (e normalmente possui destaque de sintaxe) enquanto o outro não.Minha orientação pessoal sobre métodos de nomes, parâmetros e variáveis é bastante simples:
Assim, a assinatura do método ideal, na minha opinião, seria:
Encurtar o nome do método é auto-explicativo.
O nome do parâmetro
toPad
informa imediatamente ao leitor que esse parâmetro provavelmente será modificado no local sendo preenchido e retornado. Por outro lado, nenhuma suposição pode ser feita sobre uma variável denominadarange
.Além disso, no corpo real do método, quaisquer outras
Range
variáveis introduzidas seriam (deveriam) nomeadas por suas intenções, para que você possapadded
eunpadded
...toPad
esteja em conformidade com essas convenções de nomenclatura, masrange
apenas se destaca e não gelifica.fonte
padded
/unpadded
soa bem para variáveis locais imutáveis. Porém, se houver umtoPad
parâmetro mutável , depois que o preenchimento for concluído, o nometoPad
não se ajustará mais (a menos que o resultado seja retornado imediatamente). Eu preferiria manter-meRange range
nesses casos.result
. Ele é modificado e retornado . O último é claro a partir do nome e o primeiro segue, pois retornar um argumento não modificado não faz sentido.Pad
método retorna aRange
. Isso, para mim, implica que o que eu passei será preservado, não modificado no local e um novo preenchidoRange
será retornado. .Pad(toPad)
parece IMHO meio errado. Você faz um bom ponto de defender seu ponto de vista. Você recebe um +0 de mim! :)Para nomear elementos de código (tipos, variáveis, funções, qualquer coisa), a principal pergunta a ser feita é:
Se eu digitar um erro de digitação, o compilador encontrará para mim?
O pior tipo de erro baseado em erros de digitação é aquele em que o código compila e executa, mas oferece um comportamento diferente do esperado, por motivos sutis. E como é devido a um erro de digitação, geralmente é muito difícil ver quando você está inspecionando o código. Se um erro de digitação interromper a compilação do código, o compilador sinalizará a linha que está causando o problema e você poderá encontrá-lo e corrigi-lo facilmente.
Para sua situação em que o tipo e a variável diferem apenas em letras maiúsculas, esse sempre será o caso. (Ou quase sempre - com esforço suficiente, tenho certeza de que você poderia fazê-lo funcionar, mas você precisaria realmente tentar.) Portanto, acho que você está bem por lá.
Onde você precisaria se preocupar seria se houvesse duas variáveis, métodos, funções ou propriedades no escopo atual chamado
range
eRange
. Nesse caso, o compilador provavelmente vai deixá-lo passar, e você está indo para obter um comportamento inesperado em tempo de execução. Note-se que isso é dois de qualquer um desses tipos de elemento de código, não apenas "duas variáveis" ou "duas funções" - todos esses podem ser expressos implicitamente uns aos outros, resultando em carnificina quando ele é executado. Você pode receber avisos, mas não pode garantir nada além disso. Você tem problemas semelhantes se tiver dois tipos declarados chamadosrange
eRange
.Observe também que o mesmo se aplica ao estilo de notação húngaro , onde os nomes são prefixados com um ou mais caracteres para dizer algo mais sobre o que quer que seja. Se você tem uma variável chamada
Range
e um ponteiro para elaPRange
, é fácil perder acidentalmente aP
, por exemplo. O C # deve capturar isso, mas o C e o C ++ fornecerão apenas um aviso no máximo. Ou, o que é mais preocupante, suponha que você tenha uma versão dupla chamadaDRange
e faça um downsample para uma versão flutuante chamadaFRange
. Use o flutuador por acidente (o que é fácil, já que as chaves são adjacentes em um teclado) e seu código será tipo de trabalho, mas vai cair de forma estranha e imprevisíveis quando o processo é executado fora de resolução e underflows.Já não estamos nos dias em que tínhamos limites de nomeação de 8 ou 16 caracteres ou qualquer limite arbitrário. Às vezes, ouvi novatos reclamando de nomes de variáveis mais longos, tornando a codificação mais demorada. Porém, são apenas os novatos que reclamam disso. Os codificadores sérios sabem que o que realmente leva tempo é descobrir bugs obscuros - e a má escolha de nomear é uma maneira clássica de mergulhar nesse buraco em particular.
fonte
Uma anedota que gostaria de acrescentar, embora
Range range
seja sintaticamente legal, pode tornar as coisas mais desafiadoras para depurar ou refatorar. Procurando por aquela variável chamada "range" em um arquivo com muitas variáveis do tipo Range? Você pode acabar fazendo mais trabalhos posteriormente, como resultado dessa opção de nomeação.Isso depende muito do contexto. Se for um arquivo de 30 linhas, minhas declarações não entram em jogo.
fonte
grep
é uma ótima ferramenta, mas não é uma ferramenta de refatoração. E existem ferramentas de refatoração em todas as plataformas de desenvolvimento que eu usei. (OS X, Ubuntu, Windows).Eu acho que você pode usar os dias de
Range range
hoje por um motivo: destaque da sintaxe. Os IDEs modernos geralmente destacam os nomes dos tipos e dos parâmetros em cores diferentes . Além disso, um tipo e uma variável têm uma considerável "distância lógica" que não deve ser facilmente confundida.Se esse não fosse o caso, consideraria um nome diferente ou tentaria ativar um plug-in / extensão que possa destacar essa sintaxe.
fonte
Quando uma função é genérica, é lógico que os parâmetros serão genéricos e, portanto, devem ter nomes genéricos.
Não é o que você está dizendo, mas vi funções que executam uma função genérica que têm nomes de parâmetros que são enganosamente específicos. Gostar
O nome da função parece muito genérico, pois isso pode ser aplicado a muitas seqüências de caracteres em várias situações. Mas o nome do parâmetro é estranhamente específico, me fazendo pensar se o nome da função é enganoso, ou ... o quê?
Então, ao invés de dizer Range range, você pode dizer Range rangeToPad. Mas que informações isso adiciona? Claro que é a faixa a ser preenchida. O que mais poderia ser?
Adicionar algum prefixo arbitrário, "meu" ou "m_" ou qualquer outra coisa, transmite zero informações adicionais ao leitor. Quando eu usei idiomas nos quais o compilador não permite que o nome de uma variável seja igual ao nome do tipo - com ou sem distinção entre maiúsculas e minúsculas -, às vezes coloco um prefixo ou sufixo, apenas para compilar . Mas isso é apenas para satisfazer o compilador. Alguém poderia argumentar que, mesmo que o compilador possa distinguir, isso facilita a distinção de um leitor humano. Mas uau, em Java, escrevi declarações como "Customer customer = new Customer ();" um bilhão de vezes e eu nunca achei isso confuso. (Eu sempre achei isso um pouco redundante e gosto bastante disso no VB, você pode dizer "cliente fraco como novo cliente" e não precisa dar o nome da classe duas vezes).
Onde eu objeto fortemente a nomes genéricos é quando há duas ou mais instâncias do mesmo tipo na mesma função. ESPECIALMENTE parâmetros. Gostar:
Qual é a diferença entre range1 e range2? Como eu vou saber? Se é algo em que realmente são dois valores genéricos e intercambiáveis, tudo bem, como
Eu esperaria que retornasse true se os intervalos se sobrepuserem e false se não o fizerem, portanto eles são genéricos e intercambiáveis.
Mas se eles são diferentes, me dê uma pista de como eles são diferentes! Eu estava trabalhando recentemente em um programa que tinha uma classe "Place" para armazenar dados sobre locais geográficos e com variáveis desse tipo chamadas "p", "place", "place2", "myPlace" etc. Uau, essas nomes realmente me ajudam a determinar qual é qual.
fonte