Есть разница между этими двумя. Представьте, что вы есть следующий код в File1.cs:
// File1.cs
using System;
namespace Outer.Inner
{
class Foo
{
static void Bar()
{
double d = Math.PI;
}
}
}
Теперь представьте, что кто-то добавляет другой файл (File2.cs)
в проект, который выглядит следующим образом:
// File2.cs
namespace Outer
{
class Math
{
}
}
компилятор ищет Outer, прежде чем смотреть на тех, кто использует заявления за пределами пространство имен, поэтому оно находит Outer.Math вместо System.Math. К сожалению (или, возможно, к счастью?), Outer.Math не имеет члена PI, поэтому File1 теперь сломан.
Это меняется, если вы поместите используя внутри объявления пространства имен, а именно:
// File1b.cs
namespace Outer.Inner
{
using System;
class Foo
{
static void Bar()
{
double d = Math.PI;
}
}
}
теперь поиски компилятора системы перед поиском Outer, находит System.Math, и все хорошо.
Некоторые утверждают, что Math может быть плохим именем для пользовательского класса, поскольку в системе уже есть один; дело здесь просто в том, что есть разница, и это влияет на ремонтопригодность вашего кода.
Также интересно отметить, что произойдет, если Foo находится в пространстве имен Outer, а не Outer.Inner. В этом случае добавление Outer.Math в File2 прерывает File1 независимо от того, куда идет использование. Это означает, что компилятор просматривает самое внутреннее пространство имен, перед тем как он смотрит на любые используемые операторы.
Директива * using * просто полезна, чтобы избежать необходимости вводить полное имя типа в исходный код. И применяется только к имени пространства имен, а не к имени сборки. Вы не можете использовать то, что вы не ссылаетесь, вы должны сообщить компилятору, откуда он пришел. VS2015 облегчает работу с лампочкой. –