Skip to main content

How to Resolve Error "CS0104: 'reference' is an ambiguous reference between 'identifier' and 'identifier'" in C#

The Compiler Error CS0104 is a Naming Collision error. The message reads: "'Widget' is an ambiguous reference between 'LibraryA.Widget' and 'LibraryB.Widget'".

In C#, namespaces are used to organize code and prevent naming conflicts. However, if you import two different namespaces (using the using directive) that both contain a class with the exact same name, the compiler cannot determine which one you intend to use when you type that name.

This guide explains how to resolve these conflicts using fully qualified names or aliases.

Understanding Namespace Collisions

Libraries often use common names for their classes, such as Image, Point, Button, or Logger.

  • System.Drawing has a class named Rectangle.
  • System.Windows.Shapes (WPF) also has a class named Rectangle.

If you add using System.Drawing; and using System.Windows.Shapes; to the same file, and then type Rectangle r = new Rectangle();, the compiler stops. It doesn't know if you want a drawing primitive or a UI shape.

Scenario: Importing Duplicate Class Names

Here is a simplified example involving two custom libraries that both define a class named Logger.

Setup: imagine two separate libraries referenced in your project.

  1. MyFramework.Logging (Contains public class Logger)
  2. ThirdParty.Diagnostics (Contains public class Logger)

The Ambiguous Code:

using MyFramework.Logging;
using ThirdParty.Diagnostics;

public class Program
{
static void Main()
{
// ⛔️ Error CS0104: 'Logger' is an ambiguous reference between
// 'MyFramework.Logging.Logger' and 'ThirdParty.Diagnostics.Logger'.
Logger log = new Logger();
}
}

Solution 1: Use Fully Qualified Names

The most direct fix is to be explicit. Instead of relying on the using directive to find the class, type out the entire namespace path (the Fully Qualified Name).

using MyFramework.Logging;
using ThirdParty.Diagnostics;

public class Program
{
static void Main()
{
// ✅ Correct: Explicitly choose the Framework logger
MyFramework.Logging.Logger appLog = new MyFramework.Logging.Logger();

// ✅ Correct: Explicitly choose the ThirdParty logger
ThirdParty.Diagnostics.Logger diagLog = new ThirdParty.Diagnostics.Logger();
}
}
note

While this fixes the error, typing long namespaces repeatedly can clutter your code and reduce readability.

Solution 2: Use Namespace Aliases (Cleaner Code)

If you use the conflicting class frequently in the file, typing the full namespace is tedious. C# allows you to define an Alias for a class or a namespace at the top of the file.

This tells the compiler: "In this file, whenever I type AppLogger, I mean MyFramework.Logging.Logger."

// Define Aliases using the '=' operator
using AppLogger = MyFramework.Logging.Logger;
using DiagLogger = ThirdParty.Diagnostics.Logger;

public class Program
{
static void Main()
{
// ✅ Correct: Use the alias defined above
AppLogger log1 = new AppLogger();

// ✅ Correct: Use the other alias
DiagLogger log2 = new DiagLogger();
}
}
note

Extern Alias (Advanced)

In rare cases, two assemblies might have the exact same namespace and class name. In that scenario, using aliases won't work because the namespaces themselves are identical. You would need to use Extern Aliases via the project properties (referencing the DLLs via command line aliases), usually extern alias MyLib1;.

Conclusion

CS0104 is the compiler asking for clarification.

  1. Identify the Source: The error message tells you exactly which two namespaces are fighting over the name.
  2. Quick Fix: Use the Fully Qualified Name (e.g., System.Drawing.Rectangle) for one-off usages.
  3. Clean Fix: Define a using Alias (e.g., using ProjectLog = MyLib.Logger;) at the top of the file to resolve the ambiguity while keeping code concise.