简体   繁体   中英

C# Namespace Alias qualifier (::) vs Dereferencing Operator (.)

Quick and simple question. I kind of understand what the Namespace Alias qualifier does, it's for accessing members in a namespace, however so does the dereferencing operator. I am really baffled as to the difference in this situation, why you would use one over the other, or how they each accomplish the same thing.

using colAlias = System.Collections;

namespace myns
{
    class TestApp
    {
        static void Main()
        {
            colAlias.Hashtable test = new colAlias.Hashtable();
            colAlias::Hashtable test1 = new colAlias::Hashtable();
        }
    }
}

This is a corner case :: (like the @ prefix) is there to deal with the fairly rare occurrences where a name conflicts between namespaces, classes and keywords.

:: only works for namespaces (and namespace aliases), while . . works for both namespaces and subclasses. Most places where you'd need it you'd be better off using a different name instead, but that isn't always an option.

global:: is a special case that's most often seen in auto-generated code - it resets the referenced namespace to the root.

For instance, suppose you auto-generate some code (maybe for a forms app, EF, or similar) and your app uses the namespace YourCompany.Application . Now one of your customers (using your auto-generation) decides to add their own namespace in their app TheirCompany.YourCompany.Application . Now all your auto code fails because when it compiles .Net doesn't know whether to use your namespace or theirs.

To fix this generate code with global::YourCompany.Application , then those that use your auto-generator can use whatever namespace they like and not conflict.

I think Microsoft added global:: because they expected some .Net customers to add namespaces like System .

You said:

Namespace Alias qualifier does, it's for accessing members in a namespace , however so does the dereferencing operator.

Well, no. The . operator is used to access any member, including functions. You cannot do Console::WriteLine();

:: is only for resolving namespaces, either from a namespace alias like this:

using colAlias = System.Collections;
...
...
colAlias::Hashtable test = new colAlias::Hashtable();

OR from global.

global::System.Console.WriteLine(..);

You cannot do :

System.Collections::ArrayList a = new System.Collections.ArrayList();

BUT, if you have an alias the . operator also works, so in your case , there is no difference.

There's an MSDN page explaining how this works.

Basically, in your situation they will achieve the same thing and for code readability it's preferred to use a single . .

I wouldn't use the :: operator on anything but the global namespace, and even then there are more than enough ways to work around it.

edit: More information what the operator does is explained at the :: Operator (C# Reference) article.

The general idea of a namespace qualifier is to allow you reference the namespace even if the name has been used elsewhere. If you declared a class named "colAlias" then colAlias.Hashtable would reference the class but colAlias::Hashtable would reference the namespace'd value.

This is a fairly narrow use-case and global:: is the only typical use case I have seen for this operator (When trying to ensure no conflicts can occur when creating generated code to be compiled in an unknown application).

The namespace alias qualifier (::) helps you to access namespace methods without causing errors if you have CONFLICTING namespaces using the same naming convention.

For example as explained here in msdn http://msdn.microsoft.com/en-us/library/c3ay4x3d(v=vs.80).aspx

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM