Neden “Sistem kullanıyor”; kötü uygulama olarak görülmüyor mu?


47

C ++ geçmişim var ve bu sorunun yanıtlarını tamamen anlıyorum ve kabul ediyorum: Neden “namespace std kullanıyor?” kötü uygulama olarak mı değerlendirildi?

Bu yüzden, C # ile biraz deneyime sahip olduğum için, tam tersini görüyorum: using Some.Namespace;kelimenin tam anlamıyla her yerde kullanılıyor. Bir türü kullanmaya başladığınızda, önce ad alanı için bir kullanım yönergesi eklersiniz (zaten yoksa). .csBaşlamamış bir dosya gördüğümü hatırlayamıyorum using System; using System.Collections.Generic; using X.Y.Z; etc.... Aslında, Visual Studio sihirbazı ile yeni bir dosya eklerseniz, onlara hiç ihtiyacınız olmasa bile, otomatik olarak bazı kullanma yönergeleri ekler. Yani, C ++ topluluğunda temelde linç alırken, C # bunu bile teşvik eder. En azından bana öyle geliyor.

Şimdi, C # ve C ++ direktiflerini kullanmanın aynı şey olmadığını anlıyorum. Ayrıca, using namespaceC ++ ile yapabileceğiniz en nazik şeylerden birinin , yani bir başlık dosyasına koyarak, başlık dosyaları ve bir kavram eksikliği nedeniyle C # 'da aynı derecede kötü bir muadili olmadığını anlıyorum #include.

Bununla birlikte, farklılıklarına rağmen, C # ve C ++ direktiflerini kullanmak aynı amaca hizmet eder, bu SomeTypeda çok daha uzun değil , sadece her zaman yazmak zorunda kalır Some.Namespace.SomeType( ::yerine C ++ ile .). Aynı amaçla, tehlike de benim için aynı görünüyor: Çarpışmaları adlandırmak.

En iyi durumda bu bir derleme hatasıyla sonuçlanır, bu nedenle "yalnızca" düzeltmeniz gerekir. En kötü durumda, hala derlenir ve kod sessizce yapmayı düşündüğünüzden farklı şeyler yapar. Yani sorum şu: Neden (görünüşe göre) C # ve C ++ 'da bu denli kötü sayılan yönergeleri kullanıyorsunuz?

Sahip olduğum bir cevapla ilgili bazı fikirler (bunların hiçbiri beni gerçekten tatmin etmiyor):

  • Ad alanları, C # 'da C ++ ( stdvs. System.Collection.Generic)' den çok daha uzun ve çok daha iç içe olma eğilimindedir . Dolayısıyla, kodun bu şekilde gürültüden arındırılmasında daha fazla arzu ve daha fazla kazanç vardır. Ancak bu doğru olsa bile, bu argüman yalnızca standart ad alanlarına baktığımızda geçerlidir. Özel olanlar hem C # hem de C ++ 'da istediğiniz herhangi bir kısa isme sahip olabilir.

  • Ad alanları, C # 'da C ++' dan çok daha "ince taneli" gibi görünmektedir. Bir örnek olarak, C ++ tüm standart kütüphane bulunan std(artı bazı küçük iç içe ad gibi chronoC # sen varken) System.IO, System.Threading, System.Textvb Yani, isim çakışmalarıyla riski küçüktür. Ancak, bu sadece bağırsak hissi. Aslında " using namespace stdve " ile kaç isim içe aktardığınızı saymadım using System. Ve yine, bu doğru olsa bile, bu argüman yalnızca standart ad alanlarına bakıldığında geçerlidir. Kendi olanlar hem C # hem de C ++ 'da istediğiniz kadar ince taneli olarak tasarlanabilir.

Daha fazla tartışma var mı? Özellikle gerçek gerçeklerle (eğer varsa) ilgileniyorum ve görüşlerde çok fazla değilim.


2
@Timo OP açıkça edilir değil başlık kirliliği hakkında soran.
Konrad Rudolph

1
Küresel ad alanı için C ++ ile aynı derecede rekabet olmadığı için (öncelikle C standart kitaplığı nedeniyle) olduğunu varsaydım. Ama en iyisini bilenlerin cevaplarını bekliyorum.
Wyck

2
@ThomasWeller C ++ 'ta açıktır. C # 'de Ext(this T t, long l)bununla adlandırılan bir uzantılar yöntemi düşünün t.Ext(0). Daha sonra, bir uzantı yöntemi içeren başka bir ad alanı eklerseniz Ext(this T t, int i), bunun yerine bu ad çağrılır. Ama ben C # (henüz) konusunda uzman değilim.
sebrockm

2
@Franck size bu noktayı vermiş olsam bile, aynı argüman C ++ için de geçerli, ayrıca C ++ ve C # arasındaki farkı
görmeme sorumu da itiyor

3
@Franck C ++, belirsizlik durumunda size bir derleyici hatası gönderir. Yanı sıra C #.
Timo

Yanıtlar:


28

Neden “Sistem kullanıyor”; kötü uygulama olarak görülmüyor mu?

"Sistem kullanma;" olduğu değil evrensel kötü bir uygulama olarak kabul edilmez. Örneğin bakınız: Neden C # 'kullanma' yönergesini kullanmıyorsunuz?

Ama bu oldukça kabul edilmez doğru olabilir bad olarak olarak using namespace std. Muhtemelen çünkü:

  1. C # 'da başlık dosyaları yoktur. Bir ön işlemci kullanarak bir C # kaynak dosyasını diğerine "dahil etmek" nadirdir.

  2. stdad alanı neredeyse düzdür, yani neredeyse tüm standart kitaplık işlevleri, türleri ve değişkenleri vardır (dosya sistemi alt ad alanı gibi birkaç istisna vardır). Çok, çok sayıda tanımlayıcı içerir. Anladığım kadarıyla, Systemçok daha az ad içeriyor ve bunun yerine daha fazla alt ad alanı var.

  3. C # 'da, global işlevler veya değişkenler yoktur. Bu nedenle, küresel tanımlayıcıların sayısı, aşağıdakileri içeren C ++ ile karşılaştırıldığında genellikle oldukça azdır: Ayrıca, ad alanları olmayan C kitaplıklarının (genellikle dolaylı olarak) kullanılması tipiktir ve bu nedenle tüm adlarını global olarak yerleştirir ad.

  4. Bildiğim kadarıyla, C # bağımsız değişken bağımlı arama yok. ADL, ad gizleme, aşırı yükleme vb. İle birlikte, bazı programların bir ad çakışmasından etkilenmediği durumlar üretirken, diğerleri ince bir şekilde etkilenir ve tüm köşe durumlarını yakalamak testle mümkün değildir.

Bu farklılıklar nedeniyle, “Sistem Kullanımı”; isim çatışması ihtimali daha düşüktür using namespace std.


Ayrıca, ad alanı "içe aktarma" bir bakıma, kendi kendini devam ettiren bir kuraldır: Standart bir ad alanını içe aktarmak gelenekselse, programcılar geleneksel olarak kendi tanımlayıcıları için kendi tanımlayıcıları için adları seçmekten kaçınmaya çalışırlar . böyle bir sözleşme.

Böyle bir içe aktarma işleminin kötü bir uygulama olduğu düşünülürse, programcıların içe aktarılan ad alanlarıyla bu tür çatışmalardan kaçınma girişiminde bulunma olasılığı daha düşük olacaktır. Bu nedenle, seçimler arasındaki argüman ağırlıkları başlangıçta süptil olsa bile, sözleşmeler uygulama için ya da uygulama için kutuplaşma eğilimindedir.


3
Bu, yalnızca açılış ad alanlarının olası dezavantajlarını dikkate alır. Bu bir başlangıç, ama bence de avantajları düşünmeliyiz: C ++ durumunda, çoğu durumda beş karakter tasarrufu ( std::). C # 'da, önemli ölçüde daha fazladır ( System.“yalnızca” 7 karakter vardır, ancak diğer iç içe geçmiş ad alanlarının çok daha fazla karakteri vardır ve bunları her yere yazmak kodu tamamen okunamaz hale getirir).
Konrad Rudolph

C # aşırı yük çözünürlüğünün C ++ 'dan daha kör olduğu ve derleyici hataları yoluyla çok fazla belirsizliğin ortaya çıktığı da değil mi? (
Kesinlikle

3
@KonradRudolph Dezavantajları önemli olarak kabul edilirse ve yazım miktarı eşit olarak yazılırsa (yazım miktarına kıyasla std::), using Sys = System;ad alanı takma adı olmayan diğer adı kullanmak için tipik bir stil olmaz usingmı?
eerorika

2
@Bathsheba "yetkili" ile ilgili olarak, C # hakkında çok az şey bildiğimi reddediyorum ve cevabım C ++ bilgisine ve C # hakkında birkaç google aramasına dayanıyor. Yani, eğer birisi gerçeği C # parçalarını kontrol ederse sevinirim :)
eerorika

2
ADL kısmı ile ilgili olarak: C # uzatma yöntemlerine sahiptir. ADL'den farklı bir tasarım, ancak çatışmaların adlandırılmasıyla aynı sorunları paylaşıyorlar.
Timo

-2

Ancak, farklılıklarına rağmen, C # ve C ++ yönergelerini kullanmak aynı amaca hizmet eder, bu da daha uzun bir süre yerine, sadece SomeType yazmak zorunda kalır. Aynı amaçla, tehlike de bana benziyor: Çarpışmaları adlandırmak.

Evet, ancak şu tehlikeyi dışa aktarmadınız (okuyun: başkalarını bununla başa çıkmaya zorlayın), çünkü:

Şimdi, C # ve C ++ direktiflerini kullanmanın aynı şey olmadığını anlıyorum. Ayrıca, C ++ 'da ad alanı kullanarak yapabileceğiniz en kötü şeylerden birinin, yani bir başlık dosyasına koyarak, başlık dosyaları ve #include kavramının olmaması nedeniyle C # ile eşdeğer olmadığını anlıyorum.

Yani daha farklı bir şey kategorisi.

Ayrıca, C ++, IDE'de C # ile aynı şekilde geliştirilmek üzere "tasarlanmamıştır". C # temelde her zaman Intellisense ve ne ile Visual Studio'da yazılır. Bu şekilde, onu yaratan insanlar tarafından kullanılmak üzere tasarlanmıştır. C ++ 'da geliştirmek için kaç kişinin IDE kullandığına bakılmaksızın, bu kullanım durumu ile ezici bir endişe olarak tasarlanmamıştır.

Ad alanları, C # 'da C ++' dan çok daha "ince taneli" gibi görünmektedir.

Evet, bu da. using namespace stdve using System.Collection.Generickıyaslanamaz.

Yani onları karşılaştırma!


2
Bu açıkça bir OP'ın endişe, cevap vermez değil başlıklarında ad alanlarını açma konusunda, ama uygulama dosyaları .
Konrad Rudolph

2
@KonradRudolph using namespace stdC ++ 'da kaçınılması gereken tavsiyeler çoğunlukla başlık dosyalarıyla ilgilidir. Cevap , bunun C # için geçerli olmamasıdır.
Kanatlı Asteroitler

8
@AsteroidsWithWings kaçınılması gereken tavsiye using namespace stdkesinlikle başlıklarla ilgili değildir. Üstbilgilerde kullanmak tehlikelidir. Bunu uygulamalarınızda kullanmanız tavsiye edilir.
Tommy Andersen

1
using namespace ...C ++ kaçınmak için tavsiye adlandırma çarpışma önlemek için using, C # yönergesi de çarpışma adlandırma olasılığını tanıtmak, o zaman neden kaçınmak değil? Uygulama farklı olsa da.
Tommy Andersen

@TommyAndersen, böyle bir çatışmayı çözmek ne kadar zordur? Bir saniye sürer. C # usingbildirimleri tek türü / sınıfı tanımlayan dosya başına olduğundan ve tür normal olarak bu tür ad alanı çakışmaları olasılığı nispeten dar bir dizi uygulama etki alanı kavramı (ideal olarak, tek sorumluluk ilkesi) ile ilgilidir. Ancak ne zaman kolayca sabitlenebilir. Ortak .NET geliştirme araçları / IDE bu konuda size çok yardımcı olur. Birden çok geliştirme faaliyetinin en iyisini birleştirerek sizi daha üretken hale getirmek için tasarlanmış tüm geliştirme ekosistemini düşünün
AKornich
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.