Mam doświadczenie w języku C ++ i w pełni rozumiem i zgadzam się z odpowiedziami na to pytanie: Dlaczego „używanie przestrzeni nazw std;” uważane za złą praktykę?
Jestem więc zaskoczony, że mając trochę doświadczenia z C #, widzę tam dokładnie coś przeciwnego:
using Some.Namespace;
jest dosłownie wszędzie używany. Za każdym razem, gdy zaczynasz używać typu, najpierw dodajesz dyrektywę using dla jego przestrzeni nazw (jeśli jeszcze go nie ma). Nie pamiętam, że widziałem .cs
plik, od którego się nie zaczął using System; using System.Collections.Generic; using X.Y.Z; etc...
. W rzeczywistości, jeśli dodasz nowy plik za pomocą kreatora Visual Studio, automatycznie doda tam niektóre dyrektywy, nawet jeśli w ogóle ich nie potrzebujesz. Tak więc, podczas gdy w społeczności C ++ jesteś zasadniczo zlinczowany, C # nawet zachęca do robienia tego. Przynajmniej tak mi się wydaje.
Teraz rozumiem, że używanie dyrektyw w C # i C ++ nie jest dokładnie tym samym. Rozumiem również, że jedna z najgorszych rzeczy, które możesz zrobić using namespace
w C ++, mianowicie umieszczenie go w pliku nagłówkowym, nie ma równorzędnego odpowiednika w języku C # z powodu braku koncepcji plików nagłówkowych i #include
.
Jednak pomimo różnic, korzystanie z dyrektyw w C # i C ++ służy temu samemu celowi, który trzeba pisać tylko SomeType
cały czas, a nie znacznie dłużej Some.Namespace.SomeType
(w C ++ ::
zamiast zamiast .
). I w tym samym celu również niebezpieczeństwo wydaje mi się takie samo: nazewnictwo kolizji.
W najlepszym przypadku powoduje to błąd kompilacji, więc „tylko” trzeba go naprawić. W najgorszym przypadku nadal się kompiluje, a kod po cichu robi inne rzeczy, niż zamierzałeś. Więc moje pytanie brzmi: dlaczego (najwyraźniej) używają dyrektyw uważanych za tak nierównomiernie złe w C # i C ++?
Kilka pomysłów na odpowiedź, którą mam (ale żadna z nich tak naprawdę mnie nie satysfakcjonuje):
Przestrzenie nazw są zwykle znacznie dłuższe i znacznie bardziej zagnieżdżone w C # niż w C ++ (
std
vs.System.Collection.Generic
). Tak więc istnieje większe pragnienie i większy zysk w odczekaniu kodu w ten sposób. Ale nawet jeśli jest to prawda, ten argument ma zastosowanie tylko wtedy, gdy spojrzymy na standardowe przestrzenie nazw. Niestandardowe mogą mieć dowolną krótką nazwę, zarówno w języku C #, jak i C ++.Przestrzenie nazw wydają się być znacznie bardziej „drobnoziarniste” w C # niż w C ++. Jako przykład, w C ++ cała biblioteka standardowa jest zawarta w
std
(plus kilka drobnych zagnieżdżonych nazw podobachrono
), natomiast w C # trzebaSystem.IO
,System.Threading
,System.Text
itd. Tak więc, ryzyko wystąpienia kolizji nazewnictwa jest mniejszy. Jest to jednak tylko przeczucie. Tak naprawdę nie policzyłem, ile nazw „importujesz” za pomocąusing namespace std
iusing System
. I znowu, nawet jeśli jest to prawda, ten argument ma zastosowanie tylko w przypadku standardowych przestrzeni nazw. Własne mogą być zaprojektowane tak drobnoziarniste, jak chcesz, zarówno w języku C #, jak i C ++.
Czy jest więcej argumentów? Szczególnie interesują mnie faktyczne twarde fakty (jeśli takie istnieją), a nie opinie.
źródło
Ext(this T t, long l)
która nazywa się viat.Ext(0)
. Jeśli następnie dodasz inną przestrzeń nazw zawierającą metodę rozszerzeniaExt(this T t, int i)
, zostanie ona wywołana zamiast tego. Ale nie jestem ekspertem w C # (jeszcze).Odpowiedzi:
„using System;” nie jest powszechnie uważany za złą praktykę. Zobacz na przykład: Dlaczego nie użyć dyrektywy „using” w języku C #?
Ale może być prawdą, że nie jest uważany za tak zły jak
using namespace std
. Prawdopodobnie ponieważ:C # nie ma plików nagłówkowych. Rzadko „dołącza się” jeden plik źródłowy w języku C # do drugiego za pomocą preprocesora.
std
przestrzeń nazw jest prawie płaska, tzn. są w niej prawie wszystkie standardowe funkcje biblioteczne, typy i zmienne (istnieje kilka wyjątków, takich jak podprzestrzeń nazw systemu plików). Zawiera bardzo, bardzo dużą liczbę identyfikatorów. O ile mi wiadomo,System
zawiera znacznie mniej nazw, a zamiast tego ma więcej pod-nazw.W języku C # nie ma funkcji globalnych ani zmiennych. W związku z tym liczba globalnych identyfikatorów jest zazwyczaj dość mała w przeciwieństwie do C ++, który je ma: Ponadto typowe jest używanie bibliotek C (często pośrednio), które nie mają przestrzeni nazw, a zatem umieszczają wszystkie ich nazwy w globalnej przestrzeń nazw.
O ile mi wiadomo, C # nie ma wyszukiwania zależnego od argumentów. ADL w połączeniu z ukrywaniem nazw, przeciążaniem itp. Może powodować przypadki, w których niektóre programy nie są dotknięte konfliktem nazw, podczas gdy inne są subtelnie dotknięte, a wyłapanie wszystkich przypadków narożnych nie jest możliwe przy testowaniu.
Z powodu tych różnic „używa Systemu”; ma niższą szansę na konflikt nazw niż
using namespace std
.Ponadto „importowanie” przestrzeni nazw jest w pewnym sensie samonapędzającą się konwencją: jeśli konwencjonalne jest importowanie standardowej przestrzeni nazw, wówczas programiści będą tradycyjnie starali się unikać wybierania nazw z tej przestrzeni nazw dla własnych identyfikatorów, co pomaga zmniejszyć problemy z taka konwencja.
Jeśli taki import zostanie uznany za złą praktykę, programiści będą mniej skłonni nawet próbować uniknąć konfliktów z importowanymi przestrzeniami nazw. Jako takie, konwencje mają tendencję do spolaryzowania zarówno w stosunku do praktyki, jak i przeciw niej, nawet jeśli waga argumentów między wyborami była początkowo subtelna.
źródło
std::
). W języku C # jest znacznie więcej (System.
ma „tylko” 7 znaków, ale inne, zagnieżdżone przestrzenie nazw mają o wiele więcej znaków, a zapisanie ich wszędzie sprawiłoby, że kod byłby całkowicie nieczytelny).std::
), czy nie byłoby typowym stylem stosowanieusing Sys = System;
zamiast nie-aliasu przestrzeni nazwusing
?Tak, ale nie wyeksportowałeś tego niebezpieczeństwa (czytaj: zmuszanie innych do radzenia sobie z nim), z powodu:
To raczej inna kategoria rzeczy.
Ponadto C ++ nie jest „zaprojektowany” do programowania w IDE w taki sam sposób jak C #. C # jest zasadniczo zawsze napisany w Visual Studio z Intellisense i tak dalej. Jest przeznaczony do użycia w ten sposób przez ludzi, którzy go stworzyli. Niezależnie od tego, ile osób używa IDE do programowania w C ++, nie jest on zaprojektowany z tym przypadkiem użycia jako przeważającej troski.
Tak też.
using namespace std
iusing System.Collection.Generic
są nieporównywalne.Więc nie porównuj ich!
źródło
using namespace std
w C ++ dotyczy głównie plików nagłówkowych. Odpowiedź jest taka, że nie dotyczy to języka C #.using namespace std
pewnością nie dotyczy głównie nagłówków. Używanie go w nagłówkach jest niebezpieczne. Używanie go w swoich implementacjach jest odradzane.using namespace ...
w c ++, dotyczy unikania kolizji nazewnictwa,using
dyrektywa w C # wprowadza również możliwość nazewnictwa kolizji, więc dlaczego by tego nie uniknąć? Mimo, że są różne wdrożenia.using
deklaracje w języku C # są na plik, który definiuje pojedynczy typ / klasę, a typ ten ma zwykle związek ze stosunkowo wąskim zestawem koncepcji domeny aplikacji (najlepiej zasada pojedynczej odpowiedzialności), prawdopodobieństwo takich kolizji przestrzeni nazw jest bardzo niskie. Ale kiedy to się stanie, można je łatwo naprawić. Typowe narzędzia programistyczne .NET / IDE bardzo w tym pomogą. Zastanów się nad całym ekosystemem programistycznym, który ma na celu zwiększenie produktywności, łącząc najlepsze z wielu działań programistycznych