Tenho experiência em C ++ e compreendo perfeitamente e concordo com as respostas a esta pergunta: Por que "usar o namespace std;" considerada má prática?
Então, estou surpreso que, tendo alguma experiência com C # agora, vejo exatamente o oposto:
using Some.Namespace;
é literalmente usado em todos os lugares. Sempre que você começa a usar um tipo, você adiciona uma diretiva using ao seu espaço para nome primeiro (se já não estiver lá). Não me lembro de ter visto um .cs
arquivo que não começou using System; using System.Collections.Generic; using X.Y.Z; etc...
. De fato, se você adicionar um novo arquivo por meio do assistente do Visual Studio, ele adicionará automaticamente algumas diretivas de uso, mesmo que você não precise delas. Portanto, enquanto na comunidade C ++ você é basicamente linchado, o C # até incentiva isso. Pelo menos é assim que me parece.
Agora, eu entendo que o uso de diretivas em C # e C ++ não é exatamente a mesma coisa. Além disso, eu entendo que uma das coisas mais desagradáveis que você pode fazer using namespace
em C ++, ou seja, colocá-lo em um arquivo de cabeçalho, não possui equivalente equivalente desagradável em C # devido à falta de um conceito de arquivos de cabeçalho e #include
.
No entanto, apesar de suas diferenças, o uso de diretivas em C # e C ++ serve ao mesmo objetivo, que só precisa digitar SomeType
o tempo todo, e não por muito mais tempo Some.Namespace.SomeType
(em C ++ com em ::
vez de .
). E com esse mesmo objetivo, também o perigo parece ser o mesmo para mim: nomear colisões.
Na melhor das hipóteses, isso resulta em um erro de compilação, portanto você "apenas" precisa corrigi-lo. Na pior das hipóteses, ele ainda compila e o código silenciosamente faz coisas diferentes do que você pretendia. Então, minha pergunta é: Por que (aparentemente) estão usando diretivas consideradas tão desigualmente ruins em C # e C ++?
Algumas idéias de uma resposta que tenho (nenhuma delas realmente me satisfaz):
Os espaços para nome tendem a ser muito mais longos e muito mais aninhados em C # do que em C ++ (
std
vs.System.Collection.Generic
). Portanto, há mais desejo e mais ganho em cancelar o código dessa maneira. Mas, mesmo que isso seja verdade, esse argumento só se aplica quando analisamos os espaços para nome padrão. Os personalizados podem ter qualquer nome abreviado que você queira, tanto em C # quanto em C ++.Os espaços para nome parecem muito mais "finos granulares" em C # do que em C ++. Como exemplo, em C ++ toda a biblioteca padrão está contido em
std
(além de algumas pequenas namespaces aninhados gostochrono
) enquanto em C # você temSystem.IO
,System.Threading
,System.Text
etc. Assim, o risco de ter colisões de nomeação é menor. No entanto, este é apenas um pressentimento. Na verdade, não contei quantos nomes você "importa" comusing namespace std
eusing System
. E, novamente, mesmo que isso seja verdade, esse argumento se aplica apenas ao examinar os espaços para nome padrão. Seus próprios podem ser projetados com granularidade fina, conforme desejado, em C # e C ++.
Existem mais argumentos? Estou especialmente interessado em fatos concretos reais (se houver) e não tanto em opiniões.
fonte
Ext(this T t, long l)
qual é chamado viat.Ext(0)
. Se você adicionar outro espaço para nome que contenha um método de extensãoExt(this T t, int i)
, esse será chamado. Mas eu não sou especialista em C # (ainda).Respostas:
"using System;" é não universalmente não é considerado uma má prática. Veja, por exemplo: Por que você não usaria a diretiva 'using' em C #?
Mas pode ser verdade que não é considerado tão ruim quanto
using namespace std
. Provavelmente porque:C # não possui arquivos de cabeçalho. É incomum "incluir" um arquivo de origem C # em outro usando um pré-processador.
std
O espaço para nome é quase plano, ou seja, quase todas as funções, tipos e variáveis padrão da biblioteca estão nele (existem poucas exceções, como o sub-espaço para nome do sistema de arquivos). Ele contém um número muito, muito alto de identificadores. Na minha opinião,System
contém muito menos nomes e, em vez disso, possui mais sub-nomes de espaços.No C #, não há funções ou variáveis globais. Como tal, o número de identificadores globais é tipicamente muito pequeno, em contraste com o C ++, que possui os seguintes: Além disso, é comum o uso de bibliotecas C (geralmente indiretamente) que não possuem espaços para nome e, portanto, colocam todos os seus nomes no global namespace.
Até onde eu sei, o C # não tem pesquisa dependente de argumento. A ADL em conjunto com ocultação de nomes, sobrecarga, etc. pode produzir casos em que alguns programas não são afetados por um conflito de nomes, enquanto outros são sutilmente afetados, e a captura de todos os casos de canto não é viável com o teste.
Devido a essas diferenças, "using System;" tem menor chance de conflito de nome do que
using namespace std
.Além disso, a "importação" de namespace é, de certa forma, uma convenção de autoperpetuação: se for convencional importar um namespace padrão, os programadores tentarão convencionalmente evitar escolher nomes desse namespace para seus próprios identificadores, o que ajuda a reduzir problemas com convenção.
Se essa importação for considerada uma prática ruim, é menos provável que os programadores tentem evitar esse conflito com os namespaces importados. Assim, as convenções tendem a polarizar-se a favor ou contra a prática, mesmo que os pesos dos argumentos entre as escolhas sejam originalmente sutis.
fonte
std::
). No C #, é substancialmente mais (System.
possui "apenas" 7 caracteres, mas outros namespaces aninhados têm muito mais caracteres, e escrevê-los em todos os lugares tornaria o código completamente ilegível).std::
), não seria um estilo típico usarusing Sys = System;
o espaço de nomes que polui o não-aliasusing
?Sim, mas você não exportou esse perigo (leia-se: forçando outras pessoas a lidar com ele), devido a:
Portanto, é uma categoria diferente de coisa.
Além disso, o C ++ não é "projetado" para ser desenvolvido em um IDE da mesma forma que o C #. C # é basicamente sempre escrito no Visual Studio com seu Intellisense e outros enfeites. Ele foi projetado para ser usado dessa maneira pelas pessoas que o criaram. Independentemente de quantas pessoas usem um IDE para desenvolver em C ++, ele não foi projetado com esse caso de uso como uma preocupação esmagadora.
Sim isso também.
using namespace std
eusing System.Collection.Generic
são incomparáveis.Portanto, não os compare!
fonte
using namespace std
em C ++ é principalmente sobre arquivos de cabeçalho. A resposta é que isso não se aplica em C #.using namespace std
certamente não é principalmente sobre cabeçalhos. Usá-lo em cabeçalhos é perigoso. É recomendável usá-lo em suas implementações.using namespace ...
em c ++ é sobre como evitar colisões de nomes; ausing
diretiva em C # também introduz a possibilidade de nomear colisões; por que não evitá-las? Mesmo que haja implementação diferente.using
declarações C # são por arquivo que define um tipo / classe único e o tipo normalmente tem a ver com um conjunto relativamente restrito de conceitos de domínio de aplicativo (idealmente, princípio de responsabilidade única), a probabilidade desses conflitos de namespace é extremamente baixa. Mas quando acontecem são facilmente corrigíveis. As ferramentas comuns de desenvolvimento .NET / IDE ajudam muito com isso. Considere todo o ecossistema de desenvolvimento projetado para torná-lo mais produtivo, combinando o melhor de várias atividades de desenvolvimento