Yöntem parametrelerini yeniden kullanmak kötü bir uygulama mı?


12

Yöntemin kendisinden bir yönteme geçirilen bir değeri değiştirmeniz gerektiğinde zamanlar vardır. Bir örnek, bu yöntem gibi bir dizeyi sterilize etmek olabilir:

void SanitizeName(string Name)
{
    Name = Name.ToUpper();

    //now do something here with name
}

NameArgüman referansla aktarılmadığından bu tamamen zararsızdır . Ancak, bir nedenden dolayı, gelecekteki bir geliştirici tüm değerlerin ref tarafından iletilmesine karar verirse, dizenin herhangi bir dezenfekte edilmesi, zararlı sonuçlar doğurabilecek yöntemin dışındaki değeri etkileyecektir.

Bu nedenle, argümanın kendisine yeniden atamak yerine, her zaman böyle bir yerel kopya oluştururum:

void SanitizeName(string Name)
{
    var SanitizedName = Name.ToUpper();

    //now do something here with name
}

Bu, değerin iletildiği değerin değiştirilmesinin yöntemin dışındaki durumları asla etkilemeyeceğini garanti eder, ancak bu konuda aşırı paranoyak olup olmadığımı merak ediyorum.


1
Evet, kötü uygulama; ve hayır zararsız değil. Çizgi Name = Name.ToUpper();, kodun kafanızdaki Namedeğişikliklerin değeri olarak izlenmesini zorlaştırır . İkinci örneğiniz sadece geleceğe daha dayanıklı olmakla kalmaz, ne yaptığına karar vermek daha kolaydır.
David Arno

2
Ama ne olacak if (param == NULL) param = default_value;?
aragaer

Bence evet / hayır kadar kolay değil.
MrSmith42

3
Eğer "gelecekte bir geliştirici ref tarafından geçirilen tüm değerlere sahip karar verir" , muhtemelen bir argüman olacağını dev parametre yeniden katılan veya olmasın ;-) Dürüst, tek bir değer geçmek karar verdiğinde by refo geçmedi edildi ve yerel erişimi bir nedenden ötürü yerel olmayan bir erişime dönüştürmek için, sonuçları her zaman dikkatli bir şekilde kontrol etmesi gerekir.
Doc Brown

2
Öncelikle hiçbir değişkeni yeniden atamadığımız bir paradigmada çalışıyorum . Hiç. Birinin değişkenlerin küçük bir azınlığını yeniden ataması gerekip gerekmediği ve sonra geri kalanıyla birlikte çıldırmaktan endişe etmemesi konusunda mücadele ettiğini hayal etmek komik.
Karl Bielefeldt

Yanıtlar:


10

Bence bu projenizdeki kodlama kurallarınıza bağlı.

Ben şahsen eclipse otomatik finalolarak her değişken ve parametreye anahtar kelime eklemek izin . Bu şekilde, ilk bakışta bir parametrenin yeniden kullanılıp kullanılmadığını görürsünüz.

İşimdeki projede parametreleri yeniden kullanmanızı önermiyoruz, ancak sadece örneğin çağırmak .trim()veya bir nulldurumda bir varsayılan ayarlamak istiyorsanız , parametreyi çoğu zaman yeniden kullanırız, çünkü yeni bir değişken eklemek bu gibi durumlarda daha az okunabilirdir parametrenin yeniden kullanılmasından.

Adı artık içeriğine değinmeyeceğinden, çok farklı bir içeriği depolamak için gerçekten bir parametreyi yeniden kullanmamalısınız. Ancak bu, bir değişkenin her yeniden ölçümü için geçerlidir ve parametrelerle sınırlı değildir.

Ekibinizle bir araya gelin ve bu konuyu kapsayan kodlama kurallarını formüle edin.


0

Güvenlik amacıyla statik kod analizörü kullanırsanız, kafanız karışabilir ve kullanımdan önce giriş parametresi değişkenini doğrulamadığınızı veya sterilize etmediğinizi düşünebilirsiniz. Eğer kullanırsanız Namebir SQL sorgusunda, örneğin, gizlemekte size zaman mal olacak bir SQL injection açığı, iddia edebilir. Bu kötü. Diğer yandan, sanitize edilmiş giriş için, girişi gerçekten dezenfekte etmeden, belirgin bir şekilde adlandırılmış bir değişken kullanmak, saf kod analizörlerini (yanlış negatif güvenlik açığı bulma) susturmanın hızlı bir yoludur.


Çoğu durumda, kod analizörüne bunun amaçlandığını ve fark edilmeyen bir risk olmadığını belirtmek için bir tür ek açıklama veya özel yorum kullanabilirsiniz.
MrSmith42

0

Bunun cevabı% 100 kodunuzu kimin okuyacağına bağlıdır. Hangi stilleri en yararlı buluyorlar?

En genel durumun, işlev argümanlarına değerleri yeniden atamaktan kaçındığıdır, çünkü çok fazla geliştirici, işlev çağırma işlevinin nasıl çalıştığını gösteren zihinsel modellere sahiptir. Bu sorun, her işlevi çağırdığınız bağımsız değişkenlerin değerlerini yazdıran hata ayıklayıcılar tarafından daha da kötüleşebilir. Argümanları düzenlerseniz bu bilgiler teknik olarak doğru değildir ve bu bazı garip hayal kırıklıklarına yol açabilir.

Bununla birlikte, zihinsel modeller değişir. Özel geliştirme ortamınızda, name"adın bu noktada en iyi temsili" olması arzu edilebilir. Yol boyunca değerlerinde bazı değişiklikler yapmış olsanız bile, üzerinde çalıştığınız değişkenlerin argümanlarına daha açık bir şekilde bağlanması istenebilir. Daha hantal nesneler oluşturmak yerine belirli değişkenleri yeniden kullanmanın önemli çalışma zamanı avantajları bile olabilir. Sonuçta, 4GB dizelerle çalışırken, yapmanız gereken fazladan kopya sayısını en aza indirmek güzeldir!


-1

Kod örneği ile tamamen farklı bir sorun var:

Yönteminizin adı SanitizeName. Bu durumda, bir ismi dezenfekte etmesini bekliyorum ; çünkü bu, okuyucunuza işlevinizin söylediği şeydir.

Sadece , işlemeye şey yapması gerektiğini , bir sterilize verilen bir isim . Kodunuzu okumadan aşağıdakileri beklerim:

string SanitizeName(string Name)
{
    //somehow sanitize the name
    return Result;
}

Ama sen yöntem biraz fazla yapar, ima sadece sanitizng. Bu bir kod kokusu ve kaçınılmalıdır.

Sorunuzla ilgili değil: Yöntem parametrelerini yeniden kullanmak kötü bir uygulama mı? Dahası : yan etkiler ve beklenmedik davranışlar kötü mü?

Bunun cevabı açıkça: evet!

Name argümanı referans olarak iletilmediğinden bu tamamen zararsızdır. Ancak, bir nedenden dolayı, gelecekteki bir geliştirici tüm değerlerin ref tarafından iletilmesine karar verirse, dizenin herhangi bir dezenfekte edilmesi, zararlı sonuçlar doğurabilecek yöntemin dışındaki değeri etkileyecektir.

Hiçbir şey döndürmeyerek okuyucunuzu yanıltırsınız. Yöntem adınız açıkça bir şey yaptığınızı gösterir Name. Peki, sonuç nereye gitmeli? Senin işlev imzası ile voidokur kullandığım Nameama hiçbiri id herhangi bir zarar, ne de sonuç (explicitely) anlatacaktım. Belki atılan bir istisna vardır, belki de yoktur; ancak Namedeğiştirilmez . Bu, yöntem adınızın semantikidir.

Sorun azdır yeniden daha yan etkilerde . Önlemek için yan etkileri, yok yeniden bir değişken. Herhangi bir yan etkiniz yoksa sorun yoktur.


4
-1 Bu asıl soruya cevap vermiyor. Sağlanan kod, eldeki soruyu göstermek için sadece örnek bir koddur. Sağlanan örnek kodu "saldırmak" / gözden geçirmek yerine lütfen soruyu cevaplayın.
Niklas H

1
@NiklasH Bu, soruyu mükemmel bir şekilde cevaplar: eğer parametrenin fonksiyon içinde manipüle edilmesi ve TO'nun belirttiği gibi yanlışlıkla bir kopya yerine bir referansla çalışmanız, yan etkilere (dediğim gibi) neden olur ve bu kötüdür. Bunu önlemek için, yöntem adını dikkatle seçerek (Ruby'nin '!' Düşünün) ve / veya bir dönüş türü seçerek değişkeni değiştireceğinizi belirtin. Değişkeni değiştirmezseniz, yalnızca kopyalarla çalışın.
Thomas Junk
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.