С# Namespace Alias qualifier (::) vs Dereferencing Operator (.)
Быстрый и простой вопрос. Я как бы понимаю, что делает классификатор псевдонимов Namespace, для доступа к членам в пространстве имен, однако так же работает оператор разыменования. Я действительно озадачен различием в этой ситуации, почему вы будете использовать один над другим или как каждый из них выполняет одно и то же.
using colAlias = System.Collections;
namespace myns
{
class TestApp
{
static void Main()
{
colAlias.Hashtable test = new colAlias.Hashtable();
colAlias::Hashtable test1 = new colAlias::Hashtable();
}
}
}
Ответы
Ответ 1
Это угловой случай ::
(например, префикс @
), чтобы иметь дело с довольно редкими случаями, когда имя конфликтует между пространствами имен, классами и ключевыми словами.
::
работает только для пространств имен (и псевдонимов имен), а .
. работает как для пространств имен, так и для подклассов. В большинстве мест, где вам это нужно, вам лучше использовать другое имя, но это не всегда вариант.
global::
- это особый случай, который чаще всего встречается в автоматически сгенерированном коде - он сбрасывает указанное пространство имен в корневой каталог.
Например, предположим, что вы произвольно создаете код (возможно, для приложения форм, EF или аналогичного), и ваше приложение использует пространство имен YourCompany.Application
. Теперь один из ваших клиентов (используя ваше автоматическое поколение) решает добавить свое собственное пространство имен в свое приложение TheirCompany.YourCompany.Application
. Теперь весь ваш автоматический код выходит из строя, потому что когда он компилирует .Net не знает, использовать ли ваше пространство имен или их.
Чтобы исправить этот код генерации с помощью global::YourCompany.Application
, те, которые используют ваш автогенератор, могут использовать любое пространство имен, которое им нравится, а не конфликтуют.
Я думаю, Microsoft добавила global::
, потому что они ожидали, что некоторые клиенты .Net добавят пространства имен, такие как System
.
Ответ 2
Ты сказал:
Определяет классификатор псевдонимов для доступа к членам в пространстве имен , однако так же работает оператор разыменования.
Ну, нет. Оператор .
используется для доступа к любому члену, включая функции. Вы не можете сделать Console::WriteLine();
::
предназначен только для разрешения пространств имен либо из псевдонима пространства имен, например:
using colAlias = System.Collections;
...
...
colAlias::Hashtable test = new colAlias::Hashtable();
ИЛИ из глобального.
global::System.Console.WriteLine(..);
Вы не можете делать:
System.Collections::ArrayList a = new System.Collections.ArrayList();
НО, если у вас есть псевдоним, оператор .
также работает, поэтому в вашем случае, нет никакой разницы.
Ответ 3
Здесь есть страница MSDN, объясняющая, как это работает.
В принципе, в вашей ситуации они будут добиваться того же и для чтения кода, предпочитая использовать один .
.
Я бы не использовал оператор ::
ни на чем, кроме глобального пространства имен, и даже тогда есть более чем достаточно способов обойти его.
edit: Дополнительная информация о том, что делает оператор, объясняется в :: Оператор (ссылка на С#).
Ответ 4
Общая идея спецификатора пространства имен - это позволить вам ссылаться на пространство имен, даже если имя было использовано в другом месте. Если вы объявили класс с именем "colAlias", то colAlias.Hashtable будет ссылаться на класс, но colAlias :: Hashtable будет ссылаться на значение пространства имен.
Это довольно узкий прецедент, и global::
- единственный типичный случай использования, который я видел для этого оператора (при попытке обеспечить отсутствие конфликтов при создании сгенерированного кода в неизвестном приложении).
Ответ 5
Спецификатор псевдонима пространства имен (::) помогает вам обращаться к методам пространства имен, не вызывая ошибок, если у вас есть пространства имен CONFLICTING с использованием того же соглашения об именах.
Например, как объясняется здесь в msdn
http://msdn.microsoft.com/en-us/library/c3ay4x3d(v=vs.80).aspx