C # türünde yalnızca adlandırma adından farklı olan parametre adlarını kullanmak, kasada kötü bir uygulama olarak mı kabul edilir?


43

Sınıftaki özelliklerle eşleşen parametre adlarıyla ilgili olarak buna benzer soruları görüyorum, ancak C # 'da muhafaza dışında parametre tipi adıyla aynı olan bir parametre adı kullanmayla ilgili hiçbir şey bulamıyorum. Bulabileceğim bir ihlal gibi görünmüyor, ancak kötü bir uygulama olarak mı kabul ediliyor? Örneğin, aşağıdaki yöntem var

public Range PadRange(Range range) {}

Bu yöntem bir aralık alır ve bazı dolgu uygulanmış yeni bir aralık döndürür. Bu nedenle, genel bağlamda, parametre için daha açıklayıcı bir isim düşünemiyorum. Bununla birlikte, "Psikolojik mesafe" hakkında Komple Tamam'ı okurken aldığım bir ipucunu hatırlatıyorum. Diyor ki

Psikolojik mesafe, iki maddenin birbirinden ayırt edilebileceği kolaylık olarak tanımlanabilir ... Hata ayıklarken, benzer değişken isimleri arasındaki ve benzer rutin isimler arasındaki yetersiz psikolojik mesafenin neden olduğu sorunlara hazır olun. Kod oluştururken, sorunu önleyebilmeniz için büyük farklılıklara sahip adları seçin.

Benim yöntem imzamın bir sürü "Range" olması, bu psikolojik mesafeyle ilgili bir sorun olabileceğini düşünüyor. Şimdi, birçok geliştiricinin aşağıdakileri yaptığını görüyorum

public Range PadRange(Range myRange) {}

Şahsen bu kongre için güçlü bir hoşnutsuzluğum var. Değişken adlarına "my" öneki eklemek, ek içerik sağlamaz.

Ben de aşağıdakileri görüyorum

public Range PadRange(Range rangeToPad) {}

Bunu "benim" ön ekinden daha çok seviyorum, ancak yine de genel olarak umursamıyorum. Sadece bana aşırı derecede ayrıntılı geliyor ve garip bir değişken adı olarak okuyor. Bana göre, bu aralığın yöntem adı nedeniyle doldurulacağı anlaşıldı.

Tüm bunlarla birlikte, benim bağırsaklarım ilk imzayla gitmek. Bana göre temiz. Gerekmediğinde bağlamı zorlamana gerek yok. Ama kendimi ya da gelecekteki geliştiricileri bu sözleşmeyle ilgili bir kötülük yapıyorum? En iyi uygulamayı ihlal ediyor muyum?


35
Daha açıklayıcı bir parametre bulamazsanız Range range, sorun değil.
Robert Harvey,

21
Bu durumda, IDE 'Range' ve 'range' renklerini farklı bir şekilde renklendirir; bu nedenle birinin bir tür, birinin değişken bir ad olduğunu görmek gerçekten kolaydır.
26

10
Evet, hatırladım. Tasarım kılavuzlarında bir değerlendirme olarak var. "CONSIDER bir mülke türüyle aynı adı veriyor." docs.microsoft.com/en-us/dotnet/standard/design-guidelines/…
Jason Tyler

11
Ayrıca para cezası: Range r(en azından kısa bir yöntem gövdesi için) ve Range toPad.
Bergi

19
Her zaman "benim" önekini, okuyucunun bir içeriğin bağlamına bağlı olarak başka bir şeyle değiştirilmesi gerektiğini belirtmek için kullanıldığını gösteren örnek kodda yapılan bir şey olarak düşündüm. Herhangi bir gerçek kodda bitmesi gereken bir şey değil.
kapex

Yanıtlar:


100

Bunu düşünme Range range, sorun değil. Bu tür isimleri 15 yıldan fazla bir süredir C # 'da ve muhtemelen C ++' da daha uzun süre kullanıyorum ve bundan tam anlamıyla hiçbir dezavantaj almadım.

Elbette, aynı kapsamda farklı yerel değişkenleriniz olduğunda, hepsi aynı türde, bunları düzgün bir şekilde ayırt etmek için bazı zihinsel çabalara yatırım yapmak muhtemelen yardımcı olacaktır.


6
Ekleyeceğim başka bir istisna, örneğin üzerinde belirli bir işlem yapılması durumunda. Örneğin parametrenin neden gerekli olduğu konusunda daha açıklayıcı olmak için bir miktar boş alan var. Wack (Bozo bozoToBeWacked) Parametre isteğe bağlıysa ve bu senaryodaki nesnenin ne anlama geldiğini / ne etkileyeceğini açıklıyorsa bile. Temel kural, koda bakmadan belli olmadığı takdirde, parametrenin ne yaptığı daha iyi bir isim ve / veya yorum gerektiriyor.
Mike

17
Wack(Bozo bozoToBeWacked)Değişken adında, yöntemin kendisi tarafından açıkça ifade edilen (ve böylece asıl soruya göre istenmeyen) bir artıklık örneği olarak görüyorum . Wack(Person bozo)Bununla birlikte, yalnızca anlamsız değerlerin aşağılamasının beklendiği anlamına geldiğinden daha anlamlıdır.
Miral

2
İkinci paragrafta bahsettiğiniz durumda, parametreyi sık sık benzer bir şeyle yeniden adlandırırım initialRange. Hala çok geneldir, ancak neredeyse aynı seviyedeki dengesizliğe sahip değildir myRange.
Jaquez

@Miral: Bu gibi durumlarda daha alakalı hale gelir Punch(Bozo punchingBozo, Bozo bozoToBePunched). Ayrıntılı adlandırma, birden fazla şeyi birbirinden ayırmanız gerektiğinde daha ilgilidir (bunlar hemen hemen aynı kelimelerle anlamsal olarak açıklanmaktadır). OP'nin önerisi Range rangeToPadbir parametre metodu örneğinde gerekli değildir, ancak birkaç Rangenesnede yer alan bir yöntem için inanılmaz derecede gerekli olabilir .
Flater

7
@Flater Punch(Bozo source, Bozo target)işi yapardı
Thomas Ayoub

17

Bunu her zaman yapıyorum, bana harika bir zihin veriyor. Bir üyeye atanması gereken bir kurucuya iletilen bir argümansa, üyem de range olarak adlandırılır ve atama olur.

this.range = range;

Ve genellikle Range adında bir özelliğe sahip olurdum.

Hepsi aynı şeydir, sadece bağlamda farklılık gösterir, bu nedenle tek bir ismi korumanın anlamı vardır ve sadece bir ismi hatırlamanız gerekir. Bu bir şey, farklar tamamen teknik.

"Bu" yla tam hak kazanan üyelere katı olmalısınız. Yine de StyleCop bunun için var.

StyleCop yan notu

Tartışma garantilidir!

"Bu" kullanımına karşı savunanlara: _, m, m_ ve sadece hiçbir şey görmedim. Dilin kendisi, bize bir sınıf üyesiyle karşı karşıya olduğumuzu belirtmek için bize tamamen açık ve net bir şekilde evrensel olarak tanınabilir bir yol sunuyor. Niçin dünyada zaten mükemmel isimleri kesen kendi yolunu bulmak istiyorsun?

Bunu düşünebilmemin tek nedeni, C döneminden kalma bir alışkanlık olduğunu, aslında bunu yapmanın mantıklı olduğu bir durum değildi çünkü başka bir yolu yoktu.

"Daha fazla karakter!" Ciddi anlamda? İnternethaber.com "Derleme zamanı fırlayacak!" Ciddi anlamda? "Pinky'yi yazarken kaldırmam gerekecek!" Yazma zamanının toplam gelişme zamanında bir önemi varmış gibi.

Alıştığınızdan farklı bir tarzın bazı itirazları artıracağını kabul ediyorum. Ancak bunu tutarlı bir şekilde kullanmak tartışmak zordur. İşte benim için nasıl işliyor: Yeni bir kod dosyasına basmadan önce StyleCop'u çalıştırdım ve "bu" niteleyicilere sahip olmayan bir kaç üye bulacak. "Bunu" koydum. panoda üyeler tarafından çalıştırın ve ekleyin. Hiç çaba yok.

StyleCop bundan daha fazlasını yapıyor (haha). Bir geliştiricinin (yalnızca kod biçimlendirmeyi göz önünde bulundurarak) halefinin bakım çalışmalarını engellemesinin birçok yolu vardır. StyleCop çoğunu engeller. Bu paha biçilmez.

Yeni iseniz: genellikle sizi bir veya iki hafta boyunca homurdanır ve sonra seveceksiniz.


19
Tamamen nitelikli üyelere“ bu ”diyerek katı olmalısınız . thisGerekli olmadıkça kullanmayın . Aksi takdirde sadece gürültü. _rangeAlan için kullanın ve thisuzatma yöntemleri dışında asla gerekli değildir.
David Arno

12
@DavidArno ile aynı fikirdeyim. 'bu' sadece saf ses. 'Range' bir özellik, '_range' bir alan ve 'range' bir parametredir.
26

8
@David Değişken bir sınıf üyesiyse, zorunludur ve argüman veya yerel bir değişken yerine bir sınıf üyesine baktığınızı bildirmek için herhangi bir keyfi öneki yener.
Martin Maat

6
Kendime bir değişken atadığımda IDE'm ateş toplarını vururdu.
Koekje

21
@DavidArno Neden "gürültüsünün" gürültüsünün _tercih edildiğini açıklamaya özen gösterelim this.? Birinin dilin zorladığı bir anlamı olduğunu (ve genellikle sözdizimi vurguladığını) diğeri anlamadığını söyleyebilirim.
Clint

9

Adlandırma yöntemleri, parametreleri ve değişkenleri konusundaki kendi rehberliğim oldukça basit:

  1. Ad, gönderilen veya döndürülen türü içeriyorsa, yanlış yapıyorsunuz demektir.
  2. Nesneleri ne amaçladıklarına değil, amaçlandıkları şekilde adlandırın.
  3. Her zaman kodun yazıldığından daha fazla okunduğunu unutmayın.

Böylece, en uygun yöntem imzası, bence, olacaktır:

Range Pad(Range toPad)

Yöntem adının kısaltılması kendi kendini açıklayıcı niteliktedir.

Parametre adı toPadderhal okuyucuya bu parametrenin yerine doldurularak yerinde değiştirileceğini ve sonra döndürüleceğini söyler. Buna karşılık, adlandırılmış bir değişken hakkında varsayım yapılamaz range.

Ayrıca, yöntemin gerçek vücutta başka Rangeaklınıza gelebilecek böylece tanıtıldı değişkenler, onların niyeti ile adlandırılabilir (olmalı) olur paddedve unpadded... toPadbu adlandırma kurallarına uyan, ancak rangesadece sopalarla ve jel yapmaz.


3
padded/ unpaddedYerel değişmez değişkenler için bence iyi. Ancak değişken bir toPadparametre varsa, dolum yapıldıktan sonra isim toPadartık uyuşmuyor (sonuç hemen döndürülmedikçe). Range rangeBu gibi durumlara bağlı kalmayı tercih ederim .
kapex

@Kepep sadece arayacağım result. Bu alır modifiye ve iade . İkincisi, addan açıktır ve eski, değiştirilmemiş bir argüman döndürmenin bir anlamı yoktur.
maaartinus

İmzadan, Padyöntem a döndürür Range. Bu benim için, geçtiğim kişinin yerinde kalacağı ve değiştirilmediği ve yeni bir yastığın Rangeiade edileceği anlamına geliyor. .
Aaron M. Eshbach

1
Tavsiyen hakkında ne düşüneceğimi bilmiyorum. Pad(toPad)biraz yanlış hissettiriyor IMHO. Yine de bakış açınızı savunmak için iyi bir noktaya değindiniz. Benden +0 aldın! :)
Eric Duminil,

Soruda, "bazı dolgu uygulanmış yeni bir aralık" döndürdüğü belirtiliyor. Senaryonun ne olduğunu düşündüğünüzü isimlendirmekle aynı fikirdeyim, ama asıl soru için Range CreateRangeWithPadding (Range source) gibi bir şeye giderim
Richard Willis

3

Kod elemanlarının isimlendirilmesi için (tipler, değişkenler, fonksiyonlar, her şey), kendinize soracağınız anahtar soru

Bir yazım hatası yaparsam, derleyici benim için bulur mu?

En kötü yazım hatası türlü hata, kodun derlenip çalıştığı, ancak beklediğinizden farklı davranışlar sağlayan ince davranıştır. Ve bir yazım hatası nedeniyle, genellikle kodu incelerken görmek çok zor. Bir yazım hatası kodun derlenmesini durduracaksa, derleyici soruna neden olan satırı işaretler ve kolayca bulabilir ve düzeltebilirsiniz.

Tür ve değişkenin yalnızca büyük harf kullanımı bakımından farklı olduğu durumunuz için bu her zaman böyle olacaktır. (Ya da neredeyse her zaman - yeterli çabayla, çalışmasını sağlayabileceğinden eminim, ama gerçekten denemek zorundasın.) Bence orada iyisin.

Endişelenmeniz gereken yer şu anki kapsamda rangeve denilen iki değişken, yöntem, işlev veya özellik olsaydı olurdu Range. Bu durumda derleyici muhtemelen olacaktır bunu geçmesine izin ve çalışma zamanı sırasında beklenmeyen davranışlar alacağız. Bunların ikisinin yalnızca "iki değişken" veya "iki işlev" değil, kod öğesi türlerinden herhangi biri olduğunu unutmayın - bunların tümü, çalıştırıldığında ortaya çıkan katliamla birbirlerine dolaylı olarak aktarılabilir. Uyarılar alabilirsiniz, ancak bundan daha fazlasını garanti edemezsiniz. Eğer rangeve olarak adlandırılan iki tip ilan etmiş olsaydınız benzer problemleriniz var Range.

Ayrıca, notun ne olduğu hakkında daha fazla bir şey söylemesi için adların bir veya daha fazla karakterle eklenmiş olduğu Macar gösterim tarzı için de geçerli olduğuna dikkat edin . Çağrılan bir değişken Rangeve çağrılan bir işaretçi varsa , örneğin, PRangeyanlışlıkla kaçırmak kolaydır P. C #, bunu yakalamalıdır, ancak C ve C ++ yalnızca size en çok bir uyarı verecektir. Ya da daha endişe verici bir şekilde, adlandırılmış bir çift sürümün DRangeolduğunu ve bunun adı verilen bir şamandıra sürümünün alt örneğini aldığınızı varsayalım FRange. Şamandıra (tuşlar bir klavyede bitişik olduğundan kolaydır) kazara bir ve irade kodunuzu kullanın tür çalışmaları ancak süreç çözünürlük ve underflows bittiğinde garip ve öngörülemeyen biçimlerde düşmek gerekir.

Artık 8 karakter veya 16 karakter adlandırma sınırının olduğu veya herhangi bir keyfi sınırın olmadığı günlerde artık yokuz. Bazen acemilerin, kodlamanın daha uzun sürmesini sağlayan değişken değişken isimlerden şikayetçi olduklarını duydum. Sadece bu konuda şikayetçi olan acemiler. Ciddi kodlayıcılar, gerçekte zaman alanın belirsiz böcekleri bulmak olduğunu bilir - ve yanlış adlandırma seçimi, kendinizi bu özel deliğe bırakmanın klasik bir yoludur.


Sadece okuyucular için bir not - C # için, insanlar olmalıdır gerçekten Macar Notasyonların kaçının. Eski zamanlarda, sözdizimi vurgusunun bir şey olmadığı ya da sınırlı olduğu durumlarda faydalı olsa da, bugünlerde gerçekten yardımcı olmuyor.
T. Sar - Monica

@ T.Sar O güne bile döndüm, tutkuyla nefret ettim! Söylediğiniz gibi, daha iyi IDE'ler hedeflediği problemleri çözdüler, ancak yine de her zaman bu kadar sık ​​görünüyor. Örneğin, tarihsel nedenlerle, örneğin Windows API ile konuşmanız gerekirse, yine de göreceksiniz. İnsanların tercih ettikleri tarzları gerçekten beğenmeleri halinde tamamen vurmak istemedim, ama büyük / küçük harflerin isimlendirmenin tek yolu olmadığını göstermek için bir kanca olarak kullanmak istedim.
Graham

Macar Notasyonu'nın kullanılmasını önermediğinin farkındayım, ama aynı zamanda genç devlerin havalı isimleri olan şeyler için çok büyük bir zayıflığı olduğunu da biliyorum. "Kodum bu süper gizli ninja kodlama tarzında yazılmıştır - Macar Notasyonu!" Genç beyinlere karşı konulmaz bir ses gelebilir. Ben çok fazla Devs serin kelimelerin yutturmaca kurbanı gördüm ... Macar Gösterimi ağrı kaynak kodu xx biçimindedir vermek olduğunu
T. Sar - Eski Monica

@ T.Sar Yeterince doğru. "Geçmişi hatırlamayanlar, onu tekrar etmeye mahkumdur" ve hepsi. : /
Graham

1
Orijinal Macar gösterimle bahsediyoruz ya Are o fena halde Microsoft tarafından yanlış yorumlandığını nasıl yakın ( "Windows ekibinde dokümantasyon yazarlar yanlışlıkla Sistemleri Macar olarak bilinen ne geldi icat" ve ayrıca Nirengi bölüm Leo Laporte tarafından Joel Spolsky arasında röportajda 277, 2016-12-12, 04 dakika 00 saniye - 06 dakika 35 saniye )?
Peter Mortensen

1

Ben eklemek istiyorum Bir anekdot iken Range rangebu sözdizimsel yasaldır, bu işleri daha debug veya gözden geçirmeniz zorlu yapabiliriz. Range türündeki değişkenlerin bulunduğu bir dosyada "range" adlı bir değişkeni mi arıyorsunuz? Bu adlandırma seçiminin bir sonucu olarak daha sonra daha fazla iş yapmanız gerekebilir.

Bu, büyük oranda içeriğe bağlı olsa da. 30 satırlık bir dosya ise, ifadelerim gerçekten devreye girmiyor.


7
Çoğu kişi, Windows gelişimi için türler ve parametreler veya değişkenler arasında ayrım yapan araçları kullanır. Anlattıklarınız bana Unix'teki eski güzel günleri hatırlatıyor.
Frank Hileman

1
@ FrankHileman Sizi şaşırtabilir, ama Unix hala hayatta ve grep hala kullanılıyor (: D). Grep varsayılan olarak büyük / küçük harfe duyarlı olduğundan, belirtilen sorun mevcut değildir. Bununla birlikte, biz bile, terminal bağımlısı olan pencere bağımlıları, IDE ortak aramalarda çok daha iyi olduğundan kaynak kodu için nadiren kullanılır.
maaartinus

Platformun amaç olmadığı konusunda hemfikir olduğumuzu düşünüyorum. grepharika bir araçtır, ancak yeniden düzenleme aracı değildir. Ve kullandığım her geliştirme platformunda refactoring araçları var. (OS X, Ubuntu, Windows).
Eric Wilson

@EricWilson Bir zamanlar grep ve sed, unix'teki tek refactoring aracıydı.
Frank Hileman

@ FrankHileman Bir şey refactoring aracı olarak kullanıldığı için onun bir olduğu anlamına gelmez. Not defterinde refactor yapabilir, ancak bu bir metin editöründen daha fazlasını yapmaz.
Eric Wilson

1

Sanırım Range rangebugünleri bir nedenden ötürü kullanabilirsiniz : sözdizimi vurgulama Modern IDE'ler genellikle tip adlarını ve parametre adlarını farklı renklerde vurgular . Ayrıca, bir tip ve bir değişken kolayca karıştırılmaması gereken önemli bir "mantıksal mesafe" ye sahiptir.

Böyle olmazsa, farklı bir isim düşünürdüm ya da bu sözdizimi vurgulamasını yapabilecek bir eklenti / uzantıyı etkinleştirmeye çalışırdım.


0

Bir fonksiyon genel olduğunda, parametrelerin genel olması ve dolayısıyla genel adlara sahip olması gerekliliği anlamına gelir.

Söylediğiniz şey değil, ama yanıltıcı olarak spesifik olan parametre adlarına sahip genel bir işlev gerçekleştiren işlevler gördüm. Sevmek

public String removeNonDigits(String phoneNumber)

İşlev adı çok genel bir ses çıkarır, bunun gibi birçok durumda birçok dizeye uygulanabilir. Fakat parametre ismi garip bir şekilde spesifiktir, bu da fonksiyon isminin yanıltıcı olup olmadığını merak etmeme neden oluyor mu?

Yani Range, Range range yerine Range RangeToPad diyebilirsiniz. Ama bu hangi bilgileri ekliyor? Tabii ki ped aralığı. Başka ne olabilir ki?

İsteğe bağlı bazı ön ekler "my" veya "m_" veya her neyse, okuyucuya sıfır ek bilgi iletir. Derleyicinin bir değişken adının tür adıyla aynı olmasına izin vermediği dilleri kullandığımda - büyük / küçük harf duyarlılığı olmadan - bazen derlemek için bazen bir önek veya sonek koydum . Ama bu sadece derleyiciyi tatmin etmek için. Bir derleyici ayırt edebilse bile, bunun bir insan okuyucunun ayırt etmesini kolaylaştırdığı söylenebilir. Ama vay, Java'da "Müşteri müşterisi = yeni Müşteri ();" gibi ifadeler yazdım. Bir milyar kere ve hiçbir zaman kafa karıştırıcı buldum. (Her zaman biraz gereksiz buldum ve VB'de "yeni Müşteri olarak kısık müşteri" diyebilmenizi ve sınıf adını iki kez vermek zorunda kalmamanızı seviyorum.)

Genel isimlere şiddetle karşı çıktığım yerde, aynı fonksiyonda aynı tipte iki veya daha fazla örnek olduğunda. ÖZELLİKLE parametreler. Sevmek:

public Range pad(Range range1, Range range2)

Range1 ve range2 arasındaki fark nedir? Nasıl bilebilirim ki? Gerçekten iki genel ve değiştirilebilir değer olduğu bir şeyse, tamam

public boolean overlap(Range range1, Range range2)

Eğer aralıklar üst üste binerse ve yanlışsa yanlışsa doğru dönmelerini bekliyorum, bu yüzden genel ve değiştirilebilir.

Ama eğer farklılarsa, nasıl farklı oldukları hakkında bir ipucu ver! Son zamanlarda, coğrafi yerler hakkındaki verileri tutmak için "Place" sınıfı olan ve "p", "place", "place2", "myPlace", vb. Gibi değişkenlerle çalışan bir program üzerinde çalışıyordum. isimler hangisinin hangisi olduğunu belirlememe yardımcı oluyor.

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.