[c#] 🚀 'Kullanma' direktifleri ad alanının içinde mi yoksa dışında mı olmalı?
StyleCop'u bazı C # kodları üzerinde çalıştırıyorum ve using direktiflerimin isim alanı içinde olması gerektiğini rapor ediyor .
using Yönergeleri ad alanının dışına koymak yerine teknik bir sebep var mı ?
İkisi arasında (ince) bir fark var aslında. Aşağıdaki kod File1.cs içinde bulunduğunu düşünün:
Derleyici aramalar Outer olanlar bakarak önce using isim alanı dışından direktifleri, bu yüzden bulduğu Outer.Math yerine System.Math . Ne yazık ki (veya belki de neyse ki?), Üyesi Outer.Math yok PI , bu nedenle File1 artık bozuk.
Bu using , ad alanı bildirinizi içine koyarsanız aşağıdaki gibi değişir :
Şimdi derleyici System aramadan önce arar Outer , bulur System.Math ve her şey yolundadır.
Bazıları bunun Math zaten bir tane olduğundan, kullanıcı tanımlı bir sınıf için kötü bir isim olabileceğini savunuyor System ; nokta burada orada sadece budur olduğunu fark ve bu senin kod yaşatılabilirlik etkiler.
Bunun yerine Foo , ad alanında olup bittiğini not etmek de ilginçtir . Bu durumda, Dosya2'ye ekleme , nereye gittiğinden bağımsız olarak Dosya1'i keser . Bu, derleyicinin herhangi bir yönergeye bakmadan önce en içteki çevreleyen ad alanını aradığı anlamına gelir . Outer Outer.Inner Outer.Math using using
Bu konunun zaten bazı harika cevapları var, ancak bu ek cevapla biraz daha ayrıntılı bilgi verebileceğimi hissediyorum.
İlk olarak, aşağıdaki gibi dönemlerle bir ad alanı bildiriminin:
İsterseniz using , tüm bu seviyelere direktifler koyabilirsiniz . (Tabii ki, using sadece bir yerde olmak istiyoruz , ancak dile göre yasal olur.)
: Hangi tip ima çözülmesi için kural, gevşek böyle ifade edilebilir hiçbir şey bu kadar bir sonraki kapsama bir düzey dışarı çıkmak ve orada arama orada bulunan ve eğer Birincisi, maç için iç-en "kapsam" arama , bir eşleşme bulunana kadar. Bir seviyede birden fazla eşleşme bulunursa, türlerden biri geçerli derlemeden ise, bunu seçin ve bir derleyici uyarısı verin. Aksi takdirde, pes (derleme zamanı hatası).
(1) Dışarıda yapılan kullanımlarla:
Yukarıdaki durumda, ne tür Ambiguous olduğunu bulmak için arama şu sıraya göre yapılır:
İç içe iç içe geçme türleri C (miras alınan iç içe geçme türleri dahil)
Boş ad alanındaki türler (genel ad alanı)
Türleri içinde System , System.Collections.Generic , System.Linq , MyCorp.TheProduct.OtherModule , MyCorp.TheProduct.OtherModule.Integration , ve ThirdParty
(2) içinde usings ile:
Şimdi, tür arama Ambiguous şu sırayla gider:
Türleri içinde System , System.Collections.Generic , System.Linq , MyCorp.TheProduct , MyCorp.TheProduct.OtherModule , MyCorp.TheProduct.OtherModule.Integration , ve ThirdParty
(Bunun MyCorp.TheProduct "3" ün bir parçası olduğunu ve bu nedenle "4" ve "5" arasında gerekli olmadığına dikkat edin.)
Kullanıcıları ad alanı bildirgesinin içine ya da dışına koyarsanız, her zaman birinin daha yüksek önceliğe sahip olan ad alanlarından birine aynı ada sahip yeni bir tür eklemesi olasılığı vardır.
Ayrıca, iç içe geçmiş bir ad alanı türle aynı ada sahipse, sorunlara neden olabilir.
Arama hiyerarşisi değiştiği için başkaları bir konumdan diğerine taşımak her zaman tehlikelidir, başka bir tür bulunabilir. Bu nedenle, bir kongre seçip buna bağlı kal, böylece bizi hiç kullanmayacaksın.
Visual Studio'nun şablonları, varsayılan olarak, kullanmaları ad alanının dışına yerleştirir (örneğin , VS'yi yeni bir dosyada yeni bir sınıf oluşturursanız).
Dışarıda kullanmanın bir (küçük) avantajı, örneğin [assembly: ComVisible(false)] bunun yerine global bir nitelik için kullanım direktiflerini kullanabilmenizdir [assembly: System.Runtime.InteropServices.ComVisible(false)] .
Jeppe Stig Nielsen2013-04-182013-04-18 21:00:08Z
Ad alanlarının içine yerleştirmek, bildirimleri dosya için o ad alanında yerel yapar (dosyada birden fazla ad alanı varsa), ancak dosya başına yalnızca bir ad alanınız varsa, dışarı çıkıp çıkmamaları büyük bir fark yaratmaz. ad alanının içinde.
Mark Cidade2008-09-242008-09-24 03:52:23Z
Hanselman'a göre - Yönerge ve Meclis Yüklemesini Kullanma ... ve bu tür diğer makaleler teknik olarak farketmez.
Tercihim, onları ad alanlarının dışına koymak.
Quintin Robinson2008-09-242008-09-24 03:53:21Z
StyleCop Dokümantasyonuna göre:
Neden AC # direktifini kullanarak bir ad alanı öğesinin dışına yerleştirilir.
Kural Açıklama Bu kuralın ihlali, dosya herhangi bir ad alanı öğesi içermedikçe, bir kullanım yönergesi veya bir kullanım diğerinin yönergesi bir ad alanı öğesinin dışına yerleştirildiğinde ortaya çıkar.
Örneğin, aşağıdaki kod bu kuralın iki ihlaline neden olur.
Ancak aşağıdaki kod bu kuralın ihlal edilmesine yol açmaz:
Bu kod derleyici hataları olmadan temiz bir şekilde derlenir. Ancak, Guid türünün hangi sürümünün tahsis edildiği belli değil. Eğer kullanma yönergesi aşağıda gösterildiği gibi isim alanının içine taşınırsa, bir derleyici hatası ortaya çıkacaktır:
Kod, içeren satırda bulunan aşağıdaki derleyici hatasıyla başarısız oluyor Guid g = new Guid("hello");
CS0576: 'Microsoft.Sample' ad alanı, 'Guid' takma adıyla çakışan bir tanım içeriyor
Kod, Guid adlı System.Guid türüne bir diğer ad oluşturur ve aynı zamanda eşleşen bir yapıcı arabirimiyle Guid adlı kendi türünü oluşturur. Daha sonra, kod Guid türünün bir örneğini oluşturur. Bu örneği oluşturmak için, derleyicinin Guid'in iki farklı tanımı arasından seçim yapması gerekir. Using-alias yönergesi ad alanı öğesinin dışına yerleştirildiğinde, derleyici, yerel ad alanında tanımlanmış olan yerel Guid tanımını seçecek ve ad alanının dışında tanımlanan alias kullanım direktifini tamamen göz ardı edecektir. Bu ne yazık ki kodu okurken belli değil.
Using alias yönergesi ad alanı içine yerleştirildiğinde, derleyicinin her ikisi de aynı ad alanında tanımlanmış iki farklı, çakışan Kılavuz türü arasından seçim yapması gerekir. Bu türlerin her ikisi de eşleşen bir yapıcı sağlar. Derleyici karar veremiyor, bu yüzden derleyici hatasını işaretliyor.
Takma ad direktifini ad alanının dışına yerleştirmek kötü bir uygulamadır, çünkü bu gibi durumlarda, türün hangi sürümünün kullanılmakta olduğu açık değildir. Bu potansiyel olarak teşhis edilmesi zor olabilecek bir hataya yol açabilir.
Use-alias direktiflerini ad alanı öğesinin içine yerleştirmek, bunu bir hata kaynağı olarak ortadan kaldırır.
Birden çok ad alanı
Birden çok ad alanı öğesini tek bir dosyaya yerleştirmek genellikle kötü bir fikirdir, ancak ve bu yapıldığında, yönergeleri kullanarak tüm yönergeleri, dosyanın her yerine, genel olarak her ad alanı öğesinin içine yerleştirmek iyi bir fikirdir. Bu, ad alanlarını sıkıca kapsayacak ve yukarıda açıklanan davranışlardan kaçınmaya da yardımcı olacaktır.
Kodun, ad alanının dışına yerleştirilen yönergeleri kullanarak yazarken, kodun anlamını değiştirmemesini sağlamak için bu yönergeleri ad alanına taşırken dikkatli olunması önemlidir. Yukarıda açıklandığı gibi, alias kullanma yönergelerinin ad alanı öğesinin içine yerleştirilmesi, derleyicinin, yönergeler ad alanının dışına yerleştirildiğinde oluşmayacak şekillerde çakışan türler arasında seçim yapmasına olanak tanır.
İhlalleri Düzeltme Bu kuralın ihlalini düzeltmek için, tüm yönergeleri ve ad alanı öğesinde using alias komutlarını kullanın.
Takma ad kullanmak istediğinizde, ad alanını ifadeler kullanarak yerleştirmekle ilgili bir sorun var. Takma ad önceki using ifadelerden yararlanamaz ve tam olarak nitelenmelidir.
Aşağıdakiler gibi uzun soluklu bir takma adınız varsa, bu özellikle telaffuz edilebilir (bu şekilde sorunu buldum):
Ad using alanındaki ifadelerle aniden:
Karşılaştığım bir kırışıklık (diğer cevaplarda kapsanmayan):
Bu ad alanlarının olduğunu varsayalım:
Kullandığınızda using Something.Other dışında a namespace Parent , ilki (Something.Other) ifade eder.
Ancak , bu isim alanı bildirgesinin içinde kullanırsanız, ikincisini ifade eder (Parent.Something.Other)!
Basit bir çözüm var: " global:: " öneki ekle : docs
Hans Keﬆing2019-06-052019-06-05 09:25:22Z
Jeppe Stig Nielsen'in dediği gibi , bu konunun zaten harika cevapları var, ama bu oldukça açık bir incelikten bahsetmeye değeceğini düşündüm.
using Ad alanlarında belirtilen yönergeler daha kısa kodlar oluşturabilir, çünkü dışarıda belirtildiği gibi tam olarak kalifiye olmaları gerekmez.
Aşağıdaki örnek çalışır, çünkü türler Foo ve Bar her ikisi de aynı genel ad alanındadır Outer ,.
Foo.cs kod dosyasını kabul edin :
Ve Bar.cs :
using Kısaca , dış ad alanını direktifte çıkartabilir:
Teknik sebepler cevaplarda tartışılıyor ve sonuçta kişisel tercihlere geldiğine inanıyorum, çünkü fark çok büyük değil ve her ikisi için de farklılıklar var. Visual Studio'nun .cs dosya oluşturmak için varsayılan şablonu using ad alanları dışındaki yönergeleri kullanır ;
Proje parametresinin kök dizinine dosya using ekleyerek, isim alanı dışındaki direktifleri kontrol etmek için stylecop'i düzenleyebilirsiniz stylecop.json :
Bu yapılandırma dosyasını çözüm düzeyinde oluşturabilir ve yapılandırmayı tüm projelerinizde paylaşmak için projelerinize 'Mevcut Bağlantı Dosyası' olarak ekleyebilirsiniz.
Diğer cevaplar tarafından ele alındığına inanmadığım bir başka incelik, aynı ada sahip bir sınıf ve ad alanına sahip olduğunuz içindir.
Ad alanında içe aktarma yaptığınızda, sınıfı bulur. İçe aktarma ad alanının dışındaysa, içe aktarma dikkate alınmaz ve sınıf ile ad alanının tamamen nitelendirilmesi gerekir.
Ben Gardner2018-08-242018-08-24 15:28:53Z
Bu eğer daha iyi bir uygulamadır varsayılan yani "seçeneğini kullanarak referansları ad ve olanları dışında olmalıdır kaynak çözümünde kullanılan" "Yeni eklenen referans" iyi bir uygulama size ad içine koymalıyız olmasıdır. Bu, hangi referansların eklendiğini ayırt etmektir.
Israel Ocbina2014-10-142014-10-14 21:30:07Z
Olp <p> içinde veya dışında olmalı mı?
Bir döngünün içinde veya dışında değişkenleri bildirme
Denemeli mi… yakalamak bir döngünün içine mi yoksa dışına mı?
HTML5'te, ana gezinme <header> öğesinin içinde mi yoksa dışında mı olmalıdır?
Bir iade ifadesi kilidin içinde mi yoksa dışında mı olmalıdır?
C++ 'ta C başlıklarını kullanırken, std ::' den ya da global isim alanından fonksiyonları kullanmalı mıyız?
Bir foreach döngüsü içinde veya dışında bir değişken bildirmek: hangisi daha hızlı / daha iyi?
Sınıf içinde veya dışında fonksiyon bildirimi
Güvenli olmayan bir döngü içinde veya dışında kullanmak için herhangi bir fark yaratır mı?
Metin / giriş kutularının etrafındaki odak kenarlığı (anahat) nasıl kaldırılır? (Chrome) [yinelenen]
NSStrings birleştirmek için Objective-C kısayolları
Bir geri alma yöntemi 'null' döndürmeli mi, yoksa dönüş değerini üretemediğinde bir istisna atmalı mı? [kapalı]
location.host vs location.hostname ve çapraz tarayıcı uyumluluğu?
Bu C işlevi her zaman yanlış döndürmeli, ancak değişmiyor
JQuery'de ad özelliğine sahip bir öğeyi nasıl seçerim? [çift]
Yabancı anahtar NULL olabilir ve / veya kopyalanabilir mi?