Tenho uma formação em C++ e compreendo e concordo plenamente com as respostas a esta pergunta: Porque é que "usar namespace std;" é considerado má prática?
Por isso I'estou espantado que, tendo alguma experiência com C# agora, eu veja exactamente o oposto ali:
using Some.Namespace;
é literalmente utilizado em todo o lado. Sempre que se começa a utilizar um tipo, adiciona-se primeiro uma directiva de utilização do seu espaço de nomes (se já lá estiver't). Não me lembro de ter visto um ficheiro .cs
que não't começar por usar Sistema; utilizar System.Collections.Generic; utilizar X.Y.Z; etc...
.
De facto, se adicionar um novo ficheiro através do assistente do Visual Studio, ele adiciona automaticamente algumas directivas utilizando-as, mesmo que possa não precisar delas de todo. Assim, enquanto na comunidade C++ é basicamente linchado, C# encoraja mesmo a fazer isto. Pelo menos é assim que me parece.
Agora, compreendo que a utilização de directivas em C# e C++ não são exactamente a mesma coisa. Além disso, compreendo que uma das coisas mais desagradáveis que se pode fazer com "utilizar o espaço de nomes" em C++, nomeadamente colocá-lo num ficheiro de cabeçalho, não tem equivalente equivalente desagradável em C# devido à falta de um conceito de ficheiros de cabeçalho e `#incluir'.
No entanto, apesar das suas diferenças, a utilização de directivas em C# e C++ servem o mesmo propósito, que é apenas ter de digitar SomeType
o tempo todo, em vez do muito mais longo Some.Namespace.SomeType
(em C++ com ::
em vez de .
). E com este mesmo propósito, também o perigo me parece ser o mesmo: nomear colisões.
No melhor dos casos, isto resulta num erro de compilação, portanto você "only" tem de o corrigir. No pior caso, continua a compilar e o código faz silenciosamente coisas diferentes das que pretendia fazer. Por isso, a minha pergunta é: Porquê (aparentemente) estão a usar directivas consideradas tão mal em C# e C++?
Algumas ideias de uma resposta que eu tenho (nenhuma delas me satisfaz realmente, no entanto):
Os namespaces tendem a ser muito mais longos e muito mais aninhados em C# do que em C++ (std
vs. System.Collection.Generic
). Assim, há mais desejo e mais ganho em desnudar o código desta forma. Mas mesmo que isto seja verdade, este argumento só se aplica quando olhamos para os espaços de nomes padrão. Os personalizados podem ter qualquer nome curto que se queira, em C# e C++.
Namespaces parecem ser muito mais " granular" fino; em C# do que em C++. Como exemplo, em C++ toda a biblioteca padrão está contida em std
(mais alguns pequenos espaços de nomes aninhados como chrono
) enquanto em C# tem System.IO
, System.Threading
, System.Text
, etc. Assim, o risco de ter colisões de nomes é menor. No entanto, isto é apenas uma sensação instintiva. Não contei'não contei quantos nomes você "importar" com usando namespace std
e usando System
. E mais uma vez, mesmo que isto seja verdade, este argumento aplica-se apenas ao olhar para os espaços de nomes padrão. Os seus próprios podem ser concebidos tão granularmente quanto desejar, tanto em C# como em C++.
Há mais argumentos? I'estou especialmente interessado em factos concretos concretos (se é que existem) e não tanto em opiniões.
Porque é que "usar System;" não é considerado má prática?
"usando System;" é **não*** universalmente não considerado uma má prática. Ver por exemplo: Porque não usaria o 'usando' directiva em C#?
Mas pode ser verdade que não é considerado como preensivo* como usando namespace std
. Provavelmente porque:
C# não tem ficheiros de cabeçalho. É incomum para " incluir" um ficheiro fonte C# num outro utilizando um pré-processador.
O espaço de nomes `std' é quase plano, ou seja, quase todas as funções, tipos e variáveis padrão da biblioteca estão nele (há poucas excepções, tais como o subespaço do sistema de ficheiros). Contém um número muito, muito elevado de identificadores. No meu entender, "Sistema" contém muito menos nomes, e em vez disso tem mais subespaços de nomes.
Em C#, não há funções ou variáveis globais. Como tal, o número de identificadores globais é tipicamente bastante pequeno em contraste com C++ que as tem: Além disso, é típico utilizar bibliotecas C (muitas vezes indirectamente) que não't têm espaços de nomes, e portanto colocam todos os seus nomes no espaço de nomes global.
Tanto quanto eu sei, C# não tem nenhuma procura dependente de argumentos. ADL em conjunto com a ocultação de nomes, sobrecarga, etc., pode produzir casos em que alguns programas não são afectados por um conflito de nomes, enquanto outros são subtilmente afectados, e apanhar todos os casos de canto não é viável com testes.
Devido a estas diferenças, "utilizando System;" tem menos hipóteses de conflito de nomes do que "utilizando namespace std".
Também, namespace " import" é, de certa forma, uma convenção auto-perpetuadora: Se for convencional importar um namespace padrão, então os programadores irão convencionalmente tentar para evitar escolher nomes desse namespace para os seus próprios identificadores, o que ajuda a reduzir problemas com tal convenção.
Se tal importação for considerada uma má prática, então os programadores terão menos probabilidades de tentar evitar tais conflitos com namespaces importados. Como tal, as convenções tendem a polarizar-se a favor ou contra a prática, mesmo que os pesos dos argumentos entre as escolhas fossem originalmente subtis.
No entanto, apesar das suas diferenças, a utilização de directivas em C# e C++ servem o mesmo propósito, que é apenas ter de digitar o tempo todo o SomeType, em vez de o muito mais longo Some.Namespace.SomeType (em C++ com ::: em vez de .). E com este mesmo propósito, também o perigo parece ser o meu: nomear colisões.
Sim, mas você não't exportar esse perigo (leia-se: forçar outros a lidar com ele), por causa disso:
Agora, compreendo que a utilização de directivas em C# e C++ não são exactamente a mesma coisa. Também compreendo que uma das coisas mais desagradáveis que se pode fazer com a utilização de namespace em C# e C++, nomeadamente colocá-lo num ficheiro de cabeçalho, não tem equivalente em C# devido à falta de um conceito de ficheiros de cabeçalho e #incluir.
Portanto, it's é uma categoria diferente de coisas.
Além disso, C++ não é " concebido" a ser desenvolvido numa IDE da mesma forma que C# é. O C# é basicamente sempre escrito em Visual Studio com o seu Intellisense e não só. It's concebido para ser utilizado dessa forma, pelas pessoas que o criaram. Independentemente de quantas pessoas utilizem uma IDE para desenvolver em C++, não foi concebida com esse caso de utilização como uma preocupação esmagadora.
Namespaces parecem ser muito mais " granular fino" em C# do que em C+++.
Sim, isso também. "using namespace std" e "using System.Collection.Generic" são incomparáveis.
Então não'não os compare!