Guerra de mundos: using dentro ou fora do namespace em C#
\n\nSe você já escreveu em C#, certamente já viu essa discussão nos comentários ou no Stack Overflow. Alguns desenvolvedores insistem em colocar using dentro do namespace, outros, fora. E cada um tem certeza de que sua abordagem é a única correta. Mas quem está certo? E, principalmente, isso afeta o desempenho do seu código?
Vamos de uma vez por todas esclarecer essa questão, olhar sob o capô do compilador e descobrir o que realmente acontece com suas diretivas using. Spoiler: a resposta vai te surpreender.
O que são using directives e para que servem?
\n\nAntes de mergulhar fundo, vamos relembrar o básico. As diretivas using são seu passe para o mundo de namespaces de terceiros. Sem elas, você teria que escrever nomes totalmente qualificados toda vez:
System.Console.WriteLine("Olá, mundo!");\nSystem.Collections.Generic.List<int> numbers = new System.Collections.Generic.List<int>();\n\nConcorda que parece horrível? As diretivas using tornam o código mais limpo e legível:
using System;\nusing System.Collections.Generic;\n\nConsole.WriteLine("Olá, mundo!");\nList<int> numbers = new List<int>();\n\nMas onde colocá-las é uma questão que atormenta gerações de desenvolvedores C#.
\n\nDois campos: fora vs dentro
\n\nAqui estão as duas abordagens:
\n\nOpção 1: using fora do namespace
\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace MyApp\n{\n class Program\n {\n static void Main()\n {\n List<int> list = new List<int>();\n }\n }\n}\n\nOpção 2: using dentro do namespace
\n\nnamespace MyApp\n{\n using System;\n using System.Collections.Generic;\n\n class Program\n {\n static void Main()\n {\n List<int> list = new List<int>();\n }\n }\n}\n\nÀ primeira vista, a diferença é apenas na indentação. Mas a comunidade se dividiu em dois campos irreconciliáveis. Vamos analisar os argumentos de cada um.
\n\nArgumento nº1: Desempenho e compilação
\n\nA pergunta mais comum: a localização do using afeta o desempenho? Resposta curta: NÃO. E aqui está o porquê.
As diretivas using são puramente açúcar sintático para o compilador. Elas existem apenas durante a compilação. Quando seu código se transforma em IL (Intermediate Language), não resta nenhum vestígio das diretivas using. O compilador apenas as usa para resolver nomes de tipos e depois as descarta.
Vamos provar isso na prática. Considere este código:
\n\n// Arquivo: Program.cs\nusing System;\nusing System.Collections.Generic;\n\nnamespace MyApp\n{\n class Program\n {\n static void Main()\n {\n List<int> list = new List<int>();\n Console.WriteLine(list.Count);\n }\n }\n}\n\nApós a compilação para código IL, você verá algo assim (bastante simplificado):
\n\n.method private hidebysig static void Main() cil managed\n{\n .entrypoint\n .maxstack 1\n .locals init (\n [0] class [System.Runtime]System.Collections.Generic.List`1<int32> list\n )\n \n // Criação de List<int>\n newobj instance void class [System.Runtime]System.Collections.Generic.List`1<int32>::.ctor()\n stloc.0\n \n // Chamada de Console.WriteLine\n ldloc.0\n callvirt instance int32 class [System.Runtime]System.Collections.Generic.List`1<int32>::get_Count()\n call void [System.Console]System.Console::WriteLine(int32)\n \n ret\n}\n\nObserve: no código IL, são usados nomes totalmente qualificados (System.Collections.Generic.List`1,