How to Resolve Error "CS0687: The namespace alias qualifier '::' always resolves to a type or namespace so is illegal here" in C#
The Compiler Error CS0687 is a syntax error regarding the Namespace Alias Qualifier operator (::). The message reads: "The namespace alias qualifier '::' always resolves to a type or namespace so is illegal here. Consider using '.' instead."
In C#, the double colon :: operator is strictly used to resolve Namespaces (like global::System) or Types (classes/structs) from an alias. Unlike C++, you cannot use :: to access members (methods, properties, fields, or constants) of a class. Once you have resolved the class, you must switch to the standard Member Access operator (.) to access its contents.
This guide explains the difference between these operators and how to fix the syntax.
Understanding :: vs . Operators
::(Namespace Alias Qualifier): Used to look up a class or namespace inside an alias.- Valid:
global::System - Valid:
MyAlias::MyClass
- Valid:
.(Member Access): Used to access methods, fields, properties, or nested types.- Valid:
System.Console - Valid:
Console.WriteLine
- Valid:
The :: operator creates a "Type" or "Namespace". It cannot result in a "Value" or "Action".
Scenario 1: C++ Syntax Habits (Static Members)
This is the most common cause. Developers coming from C++ are used to accessing static members using the scope resolution operator :: (e.g., std::cout, Class::Method). In C#, this syntax applies only to the alias lookup, not the member lookup.
Example of error
Attempting to access a static property or method using ::.
using System;
public class MathUtils
{
public static double Pi = 3.14159;
}
public class Program
{
static void Main()
{
// ⛔️ Error CS0687: The namespace alias qualifier '::' always resolves
// to a type or namespace.
// C# does not support 'Class::Member'.
double val = MathUtils::Pi;
}
}
Solution: Use the Dot Operator
Replace :: with ..
public class Program
{
static void Main()
{
// ✅ Correct: Use dot for member access
double val = MathUtils.Pi;
Console.WriteLine(val);
}
}
Scenario 2: Misusing the global Alias
The global:: alias is useful to avoid naming collisions by resetting the lookup to the root namespace. While you must use :: after global, you cannot use it subsequently in the chain to access members.
Example of error
Using :: to access the method after successfully resolving the class using global.
public class Program
{
static void Main()
{
// 'global::System' is Correct (resolves namespace).
// 'System.Console' is Correct (resolves class).
// 'Console::WriteLine' is WRONG (resolves method).
// ⛔️ Error CS0687
global::System.Console::WriteLine("Hello World");
}
}
Solution: Mix the Operators
Use :: only to resolve the alias, then switch to . for the rest of the chain.
public class Program
{
static void Main()
{
// ✅ Correct:
// 1. global::System (Alias lookup)
// 2. .Console (Namespace lookup)
// 3. .WriteLine (Member lookup)
global::System.Console.WriteLine("Hello World");
}
}
Rule of Thumb:
If the item on the right side of the operator is a Method, Property, or Field, you must use a dot ..
Conclusion
CS0687 acts as a syntax enforcer to distinguish C# from C++.
- Check the Operator: Are you using
::? - Check the Right Side: Is the word after
::a method (Method()) or a property?- If Yes: Change
::to.. - If No (it is a class name inside an alias): Keep
::.
- If Yes: Change