Neden alanlardaki önek önerilmez?


19

Eski günlerde, Macarca gösterim yaptık. Bu artık passé olarak kabul ediliyor ve çoğunlukla artık kullanmıyorum, ancak hala m_önek için üye alanlarını belirtmek için kullanıyorum .

Benim için, başka birinin kodunu okuyorsam ve bunu görüyorum:

count = 3;

countBu işleve yerel bir değişken olduğunu varsayalım ve işlev başka bir yerde kullanılacak bir şey yapıyorum; Bunu görürsem:

m_count = 3;

Hemen nesnenin durumunu güncellediğimin farkındayım.

Microsoft stil yönergeleri bunun bir şeyler yapmanın yanlış yolu olduğunu söylüyor. Ben ortak olmayan alanları tam olarak işlev içinde tanımlanan geçici değişkenler gibi adlandırmak gerekiyor. Hayır m_, basit bir alt çizgi bile değil.

Evet, kendi kodlama stilimizi tanımlayabiliriz, ancak daha sonra çeşitli statik kod analiz araçlarıyla güreşmek zorundayım, onları bir şeyler yapma şeklimizin iyi olduğuna ikna etmek için.

Microsoft stilini değiştirmekten mutluluk duyuyorum, ama bazı şeylerin neden böyle olduklarını bilmek isterim .

Bir değişkenin işlev yerel mi yoksa üye mi olduğunu söyleyebilmek neden kötü kabul ediliyor?

PS Bu çok benzer alanın önünde "this" anahtar kelime ve c # yöntemleri ile ilgili olarak kabul edilen en iyi uygulamaları nedir? Ama soruyorum m_değilthis.

PPS Ayrıca bkz. Microsoft neden parametreler, yerel değişkenler ve özel alanlar aynı ad adlandırma kuralına sahip?


9
C # thisanahtar kelimesine sahip değil mi? thisGibi üyelere başvuramaz this.countmısın?
SinirliWithFormsDesigner

3
M_ öneki, alanlar ve yöntemler arasında ad çakışmasını önleyen bir C ++ - ism'dir. C # 'da bu sorun değildir çünkü yöntem adları büyük harfle, küçük harfli alanlarla başlamalıdır.
amon

4
2017'de kod yazdırıyorsanız, yanlış bir şey yapıyorsunuz. Diğer iki senaryoda, countyöntemde beyan edilmediği için hiçbir yerde görünmediği oldukça açık olmalıdır . Açıkçası "IDE dışı" argümanı GERÇEKTEN zayıf. Özellikle IDE'de çalışan kod inceleme araçları olduğundan.
Andy

4
Hala Joel ile ilgili yazı .
Kasey Speakman

Yanıtlar:


19

Windows için API üzerinde çalışırken, Microsoft, 'm_' ve 'i', 'sz' vb. Kullanarak Macar Gösteriminin kullanılmasını önerdi. O zaman, IDE sağlam olmadığı için bu yararlı oldu. bu bilgiyi size göstermek için yeterli.

C # ise, başlangıçtan itibaren çok sağlam bir IDE'ye sahiptir.

Bu nedenle , genel statik veya korunan alanlar için Microsoft'un C # için Adlandırma Yönergeleri'nde öneride bulundular :

 DO use PascalCasing in field names.
 DO name fields using a noun, noun phrase, or adjective.
X DO NOT use a prefix for field names.

Artık farenizle fareyle üzerine gelebilir veya CTRL + K + W tuşlarına basabilir ve üye hakkındaki tüm bilgileri edinebilirsiniz, Microsoft öneklerin kötü form olduğuna karar verdi; onlar zaten çözülmüş bir sorunun manuel çözümdür.

Özel alanlar özellikle yönergelerden hariç tutulur, ancak Microsoft, dahili olarak ilerleyen özel alanlar için bile böyle olduğu sonucuna varmış gibi görünüyor, ki bu da Resharper'ı .NET 4.5 veya .NET Core'da işaret edip etmediğinizi görebilirsiniz.

Aletlerinizi kullanın, elle yapmayın.


2
Andy ile aynı cevap ... evet ama ... IDE dışındaki koda baktığım birçok durum var. Örnekler - (1) birleştirme araçları. (2) kod inceleme araçları. (3) (nefes nefese) çıktılar.
Betty Crokker

Andy tam anlamıyla benim yaptığım anı paylaştı. "Cevap ekle" yi tıkladığımda "1 yeni yorum" u gördüm. Bu araçlara göre, ikisi zaten IDE'de. Çıktılar ... bunu neden yapıyorsun?
Kevin Fee

1
İlk sorum cevapsız kaldı ... evet, Microsoft dedi m_ kullanmayın ve aracı üreticileri bunu takip etti, ama bu m_ kullanmak için teknik bir neden değil, genellikle "otoriteye itiraz" denir.
M_

8
@BettyCrokker Çünkü m_ kesinlikle değer katmıyor. IDE size üye olup olmadığını söyler, bu nedenle m_ tekrarlanır. Herhangi bir neden m_ üzerine sabitlenir? Neden l_ (yerel için)? Neden afsdfjdskfjas_ değil? Soruyu küçümseyeceğim, çünkü bu aptalca bir dini argüman. Ne istersen onu yap. Vurduğunuz yönergeler ayrıca "Alan adlandırma yönergeleri statik genel ve korunan alanlar için geçerlidir . Dahili ve özel alanlar _not_ yönergelerin kapsamındadır ve genel veya korunan örnek alanlarına üye tasarım yönergeleri tarafından izin verilmez"
Andy

1
@BettyCrokker Tamam, ancak bu varsayımla hazırlanmış yönergeleri soruyorsunuz. "Hiç kimse" (kabul edilebilir bir istatistiki hata payı dahilinde) C # kodlarını yazdırdığı için, bu varsayımı da kullanması muhtemel statik araçlar hakkında da şikayet ediyorsunuz. Hangi istatistiksel analiz araçlarını kullandığınızı bilmiyorum, ancak Resharper oldukça spesifik: Özel alanlar "_lowerCase" dir. Herhangi bir tür veya "UpperCase" genel üyeleri ve yerel ayarlar "lowerCase" dir. "M" tasarruf aslında oldukça hoş görünüyor.
Kevin Fee

17

C # 'ın herhangi bir global değişkeni yoktur.

Ve eğer çok sayıda yerel değişkeniniz varsa, bir tanımlayıcının bir tane olup olmadığını takip edersiniz, karmaşıklığı en kederli bir şekilde yönetme yönergelerinden birini kesinlikle ihlal etmişsinizdir.

Bir parametre nesnesini ayıklamaya çalışın, işlevinizi birden çok basit olana bölmeye çalışın, minutiae ve karmaşıklıkta boğulmayı sevmediğiniz sürece ve aynı zamanda sürdürülebilirlikle ilgili bir saygınız yoksa, kodunuzu kesinlikle yeniden düzenlemelisiniz.

Artık fonksiyon-kapsamı çok küçük olması ve küresel kapsamın mevcut olmaması nedeniyle “bu-bir-üye” -çalışmalarının amacının artık mevcut olmadığını tespit ettiğimize göre, bu belirteçlerin bir dezavantajı var: bağımsız değişkenleri / yerel değişkenleri üyelere veya başka bir yöne taşıma.


Bir kez işaret ederseniz, bir sınıf veya ad alanı da olabilir.
CodesInChaos

3
Bunun soruyu gerçekten cevapladığını sanmıyorum.
Vladimir Stokic

5
@FrankHileman Aslında öyle. Bir ismi çirkinleştirmek için neden iyi bir neden olmadığını açıklar.
Tekilleştirici

2
"uglifying"? Eğer durum buysa, bu sadece fikirli bir sorudur. Herkes çirkinlik hakkında farklı düşüncelere sahip olabilir. Bir sözleşmeyi diğerine tercih etme nedenleri vardır, ancak bu durumda standart bir sözleşme yoktur.
Frank Hileman

1
@ Duplicalicator güzellik bakanın gözündedir. Bir zamanlar çirkin olduğunu düşündüğüm sözleşmeler, artık yararlı olarak takdir ediyorum.
Frank Hileman

11

Geliştiriciler neden namespace yönergesini kullanarak ad alanlarını eklemekten kaçınırlar?

System.DateTime()çok daha açık DateTime(). Bana tam olarak neyle uğraştığımı anlatıyor. Sadece tembel daktilo olduğumuz için mi?

Hayýr. Tembel daktilolarýz, ama bu yüzden deđil.

Ayrıntıları görmezden gelmemize ve soyutlamalara odaklanmamıza izin veren kodlama stillerini tercih ediyoruz. İsimleri yapı ayrıntılarını iletmeye zorlamak dikkat dağıtıcıdır. Karmaşık bir algoritma üzerinde çalışırken, çalıştığım şeyle ilgili her küçük ayrıntıyı hatırlatmakta ısrar eden isimler istemiyorum. Sadece kafamı karıştırmamak için isme ihtiyacım var Timerve DateTime. Bunların başka bir yerde uyumlu olup olmadığı konusunda endişeleneceğim.

Jon adında ekibinizde iki adam istememenizin nedeni de aynı. Soyadlarına sahip olmaları onlara önek veya son ek vermek için bir neden değildir. Sadece sana Skeet diyeceğim. Daha fazlası her şey düz bir acıdır.


2
Bu soruya cevap vermiyor gibi görünüyor. .Net'te özel alanlar için genel bir tercih veya sözleşme yoktur.
Frank Hileman

12
@FrankHileman Genel olarak iyi isimleri tercih ediyoruz. Sözleşmeler iyi isimler oluşturmaz. Sözleşmeler McOhPlease Von StopItAlreadyStine gibi adlar oluşturur.
candied_orange

Kurallar, yalnızca farklı geliştiricinin koduyla çalışmayı kolaylaştırmak içindir. Cevabınız macarlara hitap ediyor, ancak özel alanlar için bir sözleşme yok, bu yüzden soru yanlış bir varsayım üzerine kurulu.
Frank Hileman

7

Biraz genişletelim.

C # kodunda zaman zaman karşılaşılan 3 yaygın önek stili vardır:

  • m_
  • _
  • bu.

Bu tür önekler, bir sınıfın özel uygulamasında yaygın olarak kullanılır . Microsoft önerisi öncelikle bir sınıfın açıkta kalan bölümleriyle ilgilidir.

Kullanmanın avantajı m_üzerinde _iyi gibi c # kullanırsanız önek tüm kod temeli aynı olabilir olmasıdır kullanarak farklı dillerde _bir önek izin verilmez olarak . * Avantajı m_üzerinde this.daha kısa olmasıdır ve yanlışlıkla olmaz o öneki unut.

Avantajı _over m_daha kısa olduğunu ve üst bir araç tarafından alfabetik olarak sıralanmıştır de öneki ile başlayan o şey sıralanmış olmasıdır. Avantajı _over this.daha kısa olduğunu ve yanlışlıkla öneki unutun olmayacak olmasıdır.

this.Over m_ve avantajı, kabul edilen ve evrensel bir kural olan veya olmayan bir _kod tabanında kullanabilmenizdir . Bu aynı zamanda hiç kimsenin işleri basitleştirdiği anlaşılabilecek ya da sözleşmeyi bilmesine gerek olmadığı anlamına gelir . Bir dezavantaj olarak, derleyici bu öneki umursamadığı için önek bazen eksik olacak ve bu nedenle bir gösterge kadar güvenilir olmayacaktır._m__m_this.


* _C ++ / CLI (gerçekten kullanmaması gereken _) kullanan C # sınıflarına erişmeye başladığınızda , ortak bir önek üzerinde anlaşmanın olması gerekenden daha karmaşık olduğunu fark edeceksiniz. Bir önek olmamasına karar vermek o gürültüyü ortadan kaldırır. Bunu Deduplicator'ın cevabı ile birleştirerek "ön ekin avantajı neredeyse önemsizdir" şeklinde yorumlayacağız ve bize şunu veriyor: "Ön ekleri kullanırken küçük bir sorun var ve küçük bir ters, bu yüzden sadece onları kullan".


Orada stackoverflow eski soru bu ilgili.


1
Güzel karşılaştırma. Ancak, herhangi bir önek kullanmanın pratikte iyi sonuç verdiğini düşünüyorum.
Phil1970

6

MS stil rehberinin sadece kamusal ve korunan yöntemler ve değişkenler hakkında konuştuğuna dikkat edilmelidir. yani diğer geliştiriciler kütüphanenizi kullanıp kullanmadıklarını göreceklerdir.

Fikir, Microsoft kütüphanelerine bunları tüketen geliştiricilere standart bir görünüm ve his verilmesi.

Özel veya yerel değişkenlerinizde istediğiniz stili kullanmakta özgürsünüz.

Değişken öneklerin genel olarak çeşitli nedenlerden dolayı cesaretinin kırıldığını söylemiş olmak

  • Yanlış olabilirler ve dolayısıyla yanıltıcı olabilirler
  • Değişken türüne göre önek ekliyorsanız, oluşturduğunuz sınıfları nasıl işlediğiniz net değildir.
  • Çok sayıda sözleşme var ve her zaman aynı fikirde değiller. Yararlı bulduğunuz başka bir geliştirici yararsız olabilir
  • Üye değişkenleri durumunda bunu 'bu' kullanabilirsiniz. kapsamı belirtmek için anahtar kelime ve karşılaştırıcı onu zorunlu kılar.

2
Başlangıçta alanlar için hiç önek kullanmadım. Daha sonra, IDE açılır liste kutularını kullandığınızda tüm alanları alfabetik üye listesinin en üstüne taşıdığı için başkalarını kullanırken gördüğüm gibi tek bir "_" karakteri kullanmaya geçtim. Standart bir sözleşmenin olmaması, birçok farklı geliştirici tarafından yazılan kodları okurken can sıkıcı olabilir.
Frank Hileman

Bir süre sonra çok fazla farklı stil görüyorsunuz. Eğer bir tarzı güçlendirmeye çalışırsanız, sürekli olarak her şeyi yeniden düzenlersiniz
Ewan

4
"Yanlış olabilirler ve dolayısıyla yanıltıcı olabilirler" i çoğu şeye uygularsanız, değişkenleri veya işlevleri adlandırmamanız gerektiğini çabucak keşfedersiniz - sonuçta yanlış olabilirler! Ve ikinci mermi noktanızın "yaratmadığınız sınıflar" demesi gerektiğini tahmin ediyorum. Yoksa sadece anlamıyorum ... Her halükarda, kamuya açık olmayan alanlar için tek bir alt çizgi önekinin olması gayri resmi bir standart gibi geliyor, muhtemelen gideceğimiz yön bu.
Betty Crokker

bazı şeyler derleyici tarafından kontrol edilir, bu yüzden m_count bir üye değişken olmayabilir, ancak this.count her zaman olacak
Ewan

ppl bir sürü _ _ kullanır ama zamanla işler değişir, geçen yıl 'en iyi uygulama' için yazılan kodun bu yılki kurallarla eşleşmediğini
Ewan

4

Benim için, başka birinin kodunu okuyorsam ve bunu görüyorum:

count = 3;

Ben 'saymak' bu fonksiyon için yerel bir değişken olduğunu varsayalım ve fonksiyon başka bir yerde kullanılacak bir şey yapıyorum

Ve kesinlikle doğru olacaktır eğer C # 'ın stil kuralları saygı kaynak kodunu okuyor. Bu kodda:

this.count = 3;

bir alana bir değer atar.

count = 3;

yerel bir değişkene bir değer atar.

Bu nedenle, C # 'ın stil kuralları açık ve nettir. Sizi herhangi bir öneki kullanmamaya zorlarlar çünkü sadece bir önek gerekmez.

Yazarlar yerine kendi kişisel kuralları kullanmaya karar hangi kaynak kodu için olduğu gibi, sormalısınız onları bunu yapmak için bir seçim yaptı neden şahsen. Alt çizgi gibi önekleri kullanmazlarsa, this.her ikisini de kullanmazlarsa , yalnızca kodu okumak zor değil, aynı zamanda ek bir kuralın gerekli olacağı durumlara da etkili olurlar :

public class Hello
{
    private string greetings;

    public Hello(string greetings)
    {
        greetings = greetings; // Wait, what is that?!
    }
}

C # bu anahtar kelimeye sahip değil mi? This.count gibi bunu kullanan üyelere başvuramaz mısınız?

Evet, ancak (1) daha fazla yazı yazmak ve (2) unutmak kolaydır. Alan m_count olarak adlandırılırsa, bunu yazmayı hatırlamam gerekmez. M_count

Ancak burada yanılıyorsunuz.

Kodunuzu Not Defteri'ne yazdığınızda daha fazla yazabilirsiniz. Bir otomatik tamamlama IDE ya da daha, ıntellisense arasındaki karşılaştırma ile this.countve m_countbelirgin olarak değil. Alt çizgiyi yazmak için gereken Shift+ işaretini not edin -.

“Unutması kolay” söz konusu olduğunda, bu sadece Not Defteri kullanıcıları için geçerlidir. Sadece StyleCop ve Resharper, this.gerektiğinde koymayı unutmanıza izin vermez , aynı zamanda birkaç saatlik programlamadan sonra, this.gerektiğinde koymak bir alışkanlık haline gelir.


6
thisSadece ihtiyacınız olduğunda kullanmanın gerçekten tutarsız bir his verdiğini ve beni çok sık rahatsız ettiğini görüyorum . thisBir önek yerine kullanacaksanız , her zaman kullanmanız gerektiğine inanıyorum . Bu durumda, bir önek olur ve siz de kullanabilirsiniz _.
RubberDuck

1
RubberDuck haklı. "bu." bir önek olmasına rağmen derleyici anlamı vardır.
Frank Hileman

4

"Üye" öneki bir tür uygulama detayıdır. Dikkatinizi, sorunlu alandan, olası yeniden düzenlemeleri düşünürken zihninizi saptıran teknik çözüm alanına dağıtır. - ben mi

daha fazla açıklayabilir misin Sizinki öneki kullanmamanın tek sebebi seninki ve bunu anlamıyorum ... neden olmamamla aynı değil) - Betty Crokker

Demek istediğim @CandiedOrange ve @Ewan'ın cevaplarını genişletmek.

Ön ekler yeniden düzenlemeyi zorlaştırır

Kodunuz geliştikçe değişkenler ve yöntemler kapsamlarını değiştirebilir. Örneğin. özel bir yöntem oluşturabilir ve daha sonra diğer (yeni) sınıflar için de kullanılabilir olması gerektiğini öğrenebilirsiniz. Benzer yöntem parametreleri ve yerel değişkenler için de olabilir.

Vergi hesap makinesi oluşturduğunuzu varsayalım. Hem vergi oranını hem de taban değerini parametre olarak alan bir yöntemle başladığınız değişkenler için kira görünürlüğü kapsamı ilkesine göre : (örnek Java-ish ... gibi görünebilir)

class TaxCalculator{
   double Calculate(double p_TaxRateInpercent, double p_BaseValue){
     return (100+p_TaxRateInpercent)/100 * p_BaseValue;
   }
} 

sonra ters işlemi uygulamanız gerekir ve TDD'ye göre bunu en az çaba ile yaparsınız:

class TaxCalculator{
   double Calculate(double p_TaxRateInpercent, double p_BaseValue){
     return (100+p_TaxRateInpercent)/100 * p_BaseValue;
   }
   double CalculateBase(double p_TaxRateInpercent, double p_TaxedValue){
     return p_TaxedValue/((100+p_TaxRateInpercent)/100);
   }
} 

Sonraki TDD, her iki yöntemin parametre listesini azaltmak için daha temiz hale gelmek için kodu yeniden düzenlemenizi ister.
(Evet, önce iki katına çıkmış hesaplamayı çıkartabilirsiniz, ama benim açımdan anlayayım ...)
Açık çözüm, vergi oranını bir yapıcı parametresi olarak geçirerek üye değişkenine dönüştürmektir.

class TaxCalculator{
   double m_TaxRateInpercent;
   TaxCalculator(double p_TaxRateInpercent){
     m_TaxRateInpercent = p_TaxRateInpercent;
   }
   double Calculate(double p_BaseValue){
     return (100+m_TaxRateInpercent)/100 * p_BaseValue;
   }
   double CalculateBase(double p_TaxedValue){
     return p_TaxedValue/((100+m_TaxRateInpercent)/100);
   }
} 

Gördüğünüz gibi mevcut yöntemlerimizin tüm satırlarını değiştirmek zorunda kaldık (önceden kullandığımız herhangi bir satır p_TaxRateInpercent.

Sorun, sınıf boyunca yeniden adlandırma yapmak için IDE'nizden destek almamanızdır. Arama / değiştirme konusunda tek yardımcı , kurucuyu veya yanlışlıkla dizeyi içeren herhangi bir parçayı da değiştirir p_TaxRateInpercent.
IDE , tanımlanmamış değişken adları için ... yeniden düzenleme işleminde bir değişiklik önerebilir, ancak bu yöntemin kapsamıyla sınırlı olabilir

Önek olmadan sadece yöntem imzaları değişebilirdi. Hiçbir yeniden adlandırma gerekmeyecekti.


Önek değiştiğinde SCM geçmişini karıştırır

Ayrıca, mantık değişmese de SCM önek değişikliğini mantıktaki değişiklikler olarak kaydeder! SCM'lerin geçmişi, önemli olanı gizleyen ve başkalarının (gerçek mantık) değişiklikleriyle çatışma riskini artıran bu teknik değişiklikle doludur.


1

Tüm üye değişkenler için _ öneki kullanıyorum. 'Bu' önekten nefret ediyorum, çünkü bazıları bir şeyler yapmanın doğru yolu olduğunu iddia ederken - kod tabanınıza çok fazla gürültü / karmaşa ekliyor. Microsoft'un örneklerinde tek bir alt çizgi de yaygın bir uygulamadır.

Yani örneğinizde:

int _count = 10;
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.